惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
C
Check Point Blog
GbyAI
GbyAI
Jina AI
Jina AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 司徒正美
Hacker News - Newest:
Hacker News - Newest: "LLM"
V2EX - 技术
V2EX - 技术
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
F
Full Disclosure
S
Secure Thoughts
WordPress大学
WordPress大学
博客园 - Franky
N
News and Events Feed by Topic
雷峰网
雷峰网
www.infosecurity-magazine.com
www.infosecurity-magazine.com
H
Hacker News: Front Page
N
Netflix TechBlog - Medium
Forbes - Security
Forbes - Security
TaoSecurity Blog
TaoSecurity Blog
C
CERT Recently Published Vulnerability Notes
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss
MyScale Blog
MyScale Blog
Security Latest
Security Latest
Attack and Defense Labs
Attack and Defense Labs
The Register - Security
The Register - Security
Spread Privacy
Spread Privacy
H
Help Net Security
宝玉的分享
宝玉的分享
L
LangChain Blog
MongoDB | Blog
MongoDB | Blog
I
Intezer
Schneier on Security
Schneier on Security
Latest news
Latest news
Y
Y Combinator Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
I
InfoQ
A
About on SuperTechFans
T
Tor Project blog
Microsoft Security Blog
Microsoft Security Blog
M
MIT News - Artificial intelligence
Google DeepMind News
Google DeepMind News
Microsoft Azure Blog
Microsoft Azure Blog
T
Threat Research - Cisco Blogs
S
Schneier on Security
Cisco Talos Blog
Cisco Talos Blog
H
Heimdal Security Blog

WAYJAM

告别 NPM Token:迁移到 Trusted Publishing 全记录 Sing-box:IPv6 优先出站与 Netflix 强制 IPv6 分流 [All In One] HomeLab 虚拟化 iKuai + Mihomo - IPv6 支持 [All In One] HomeLab 虚拟化 iKuai + Mihomo LiteLLM 多模型 API 中转 MacOS Bootstrp with Nix Fluency Support Full Rss [All In One] PVE 中 OpenWrt LXC 重启问题 Tabby 终端配置以及配置全平台同步 Cloudflare Tunnel + Nginx Proxy Manager:服务穿透 PVE 7 升级 8 笔记 PVE 安装 Android x86 & 安装 Magisk Fly.io 部署 Artalk 评论系统 [All In One] HomeLab 2023 搭建总结 [All In One] 轻量的文件 & 媒体服务器配置 [All In One] R71s 主机散热改造 [All In One] PVE LXC 安装 OpenWrt 软路由以及网络规划 [All In One] 安装 Proxmox VE 7.4 从零开始配置Rime - 2023 Self Hosted Bitwarden + Cloudfare HTTPS Debian NFS Server 以及 MacOS Client AdguardHome 和 Clash 透明代理配合使用 使用 Kind 部署 Prow 手记 BackBlaze B2 + Cloudfare Worker 图床 PicGo Amazon S3 插件 自动给模板生成 Inline-Svg Hugo Theme WeUI 发布! Hugo Theme Fluency 发布! Docker Clash 和 透明代理 有限状态机与分布式熔断器 「家庭娱乐」N1刷 EmuELEC 做游戏盒子 「家庭娱乐」N1刷 Armbian 做家庭服务器 分布式限流器之令牌桶实现 Kustomize 管理 Kubernetes 集群 Mixedpaper 主题发布到 Hugo 官方仓库 About 优化 Docker 构建时间 解决 etcd 与 grpc 不兼容问题 Kubernetes 部署 ElasticSearch7 集群 从零开始配置Rime - 2019 转移域名,更换评论系统,更换图床 搭建 NPM Proxy 之预编译包 搭建 NPM Proxy 美区Apple ID终于绑定PayPal成功 无可奈何的页面增强方案 LogStash的调试 GitLab Shell如何通过SSH工作 荒原 [Theme] Bitcron主题Mixedpaper发布! Ngrok端口转发 故事之五 - 柠檬茶 故事之四 - 我是天才 故事之一 Arch滚挂了怎么办? OpenWrt内网IPv6之二 某次更新后Primusrun不能启动Dota2 OpenWrt的DNS智能解析方案 替换Google CDN库 使用Privoxy将socks代理转化为http代理 ArchLinux之软件篇 再次安装ArchLinux手记 博客再次重生 搞了个Minecraft服务器 【LnV工作室荣誉出品】小苹果MV华农大版 雨梦 醉臥石中笑人間 路由器内网IPV6地址分配 OPENWRT安装软件的两个问题 路由器上进行锐捷认证 改了BIOS的LOGO Windows下搭建我的C/C++的开发环境 Linux下用Mentohust认证校园网 Archlinux+Windows 双系统安装手记(UEFI+GPT) Google-code-prettify代码高亮 《末世迷踪》 Hello Net World!
Python打开类
2018-06-27 · via WAYJAM

Ruby可以直接打开一个已定义的类(模块),打开与定义与其他语句没有本质区别,第二次使用class关键字之后,之后的语句就是进入这个类的封闭作用域内进行一些操作。

在Python中,类只允许一次有效定义,每使用一次class关键字,都作为一个独立的定义类操作。

在Python里面,需要定义或修改方法、属性不需要专门的“打开”,在专门的作用域里面操作。

def hi():
    return 'hi'

class Klass:
    pass
Klass.attr1 = 1
klass.method1 = hi

但每次先定义一个函数然后再“赋值”的代码感觉不够优美,这里可以通过装饰器,即定义一个未绑定函数,然后返回装饰后的“绑定”函数。方法参考:在 Python 中实现 Ruby 的 Open Class 和特异方法

Python的面向对象特征是建立在基于函数的环境之上的。Class的方法以函数的方式定义在类中,当访问一个方法的时候:

class Klass: pass
Klass.a_method # => Klass.__dict__[a_method].__get__(Klass) => unbound function in py2k, raw function in py3k
instance = Klass()
instance.a_method # => type(instance).__dict__[a_method].__get__(instance, type(instance)) => bound function

上面的例子说明了,访问一个类方法的时候,实际上是在当前类(实例的元类)的属性字典中根据方法名查找到对应方法(不存在则调用__getattr__方法),然后调用函数的__get__方法(函数也是对象),这个方法的两个参数实际上决定了目标函数是一个普通函数、静态方法、类方法还是实例方法等,以及执行的上下文实体,意思就是描述符在你要调用一个方法的时候将obj.f(*args)转换成了f(obj, *args)Klass.m(*args)转换成了m(*args)

所以,在类中新增方法有一种写法,在实例中新增绑定方法有三种写法(可以理解为将实例绑定到函数对象):

  • 偏函数
  • 描述符
  • Types声明
from functools import partial
from types import MethodType

def attach_method(target):
    if isinstance(target, type):
        # 类
        def decorator(func):
            setattr(target, func.__name__, func)
    else:
        # 实例
        def decorator(func):
            # bound_func = partial(func, target) # partial function
            # bound_func = func.__get__(target)  # descriptor
            bound_func = MethodType(func, target)  # types
            setattr(target, func.__name__, bound_func)
            
    return decorator

或者说再写一个装饰器,装饰新定义的类,将新类的属性和方法attach到原同名类内,达到类似“打开”类操作的效果,但只能重定义,而不能够真正使用原类中的变量或方法 。但是,实例写一个类似的instance_eval的话,只能装饰在def或者class关键字上,使用上并不直观。

def class_eval(obj):
    original_obj = globals().get(obj.__name__)
    for k, v in obj.__dict__.items():
        if k not in ['__dict__', '__weakref__']:
            attach_method(original_obj)(v, k) 
    return original_obj

@class_eval
class Klass:  # same class name
    new_attr: 1
    def hi(self):
        return "Hello"

以上就是绑定函数或属性到对象(类)。