gpt4 book ai didi

python - 装饰一个类 - 装饰一次就忘记了?

转载 作者:行者123 更新时间:2023-12-01 05:49:44 25 4
gpt4 key购买 nike

我成功创建了一个装饰器,可以装饰任何类型的类,为它们添加一个标准接口(interface),以便于访问、集成等......

我一直拒绝使用元类,因为关于这一点的文献表明它是一种矫枉过正的行为,而且大多数时候可以用类装饰器来代替。令我困扰的是以下几点:

def Decorator(somearg):

def wrapper(cls):
clsinit = cls.__init__
cls.members = []

def __init__(self, *args, **kwargs):
#do something with somearg...
self.__class__.members.append(self)
clsinit(self,*args,**kwargs)

cls.__init__ = clsinit
return cls

return wrapper

@Decorator('thearg')
class A(object):
pass

a = A()
b = A()

使用 python 调试器,在导入时,类 A 立即用参数“thearg”修饰。但每次我实例化 A() 时,实例都会直接调用装饰器中定义的 init,而不经过前面的层。这很好,因为我希望我的类记录每个成员,而不是在每次实例化新实例时重置。但我不确定我明白为什么。

有人可以解释一下在这个特定情况下Python解释器的物理原理吗?

最佳答案

如果您只是更改类而不是创建新类,则不需要包装函数(应该是包装类):

def Decorator(cls):
clsinit = cls.__init__
cls.members = []

def __init__(self, *args, **kwargs):
clsinit(self, *args, **kwargs)
self.__class__.members.append(self)

cls.__init__ = __init__
return cls

顺便说一句,您应该只创建一个基类并从中继承:

class Base(object):
members = []
def __init__(self):
self.__class__.members.append(self)

class A(Base):
pass

干净多了

关于python - 装饰一个类 - 装饰一次就忘记了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14784474/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com