我成功创建了一个装饰器,可以装饰任何类型的类,为它们添加一个标准接口(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/