我成功地创建了一个装饰器来装饰任何类型的类,并为它们添加了一个标准接口,以便于访问、集成等。。。在
我一直反对使用元类,因为在这一点上的文献认为这是一种过度使用,而且大多数时候可以被类装饰器所取代。让我烦恼的是:
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()时,实例都直接调用decorator中定义的init,而不经过前面的层。这很好,因为我希望我的类记录每个成员,而不是每次实例化新实例时都重置。但我不知道为什么。在
有人能解释一下python解释器在这个特殊情况下的物理原理吗?在
如果只是更改类而不是创建新类,则不需要包装器函数(应该是包装器类):
顺便说一句,您应该创建一个基类并从中继承:
^{pr2}$干净多了
更新后的问题,请参考您的代码:
它这样做是因为当}的{}。每当
Decorator()
函数创建的wrapper()
类修饰符函数应用于class A
时,它用自己动态定义的wrapper.__init__()
替换了{A
s被实例化时,函数就是被调用的函数,它首先被写出来做一些事情,然后在最后调用原始的A.__init__()
。在感谢@JBernardo和@martineau的回答。我使用这段代码的目的是实现类对象的类似容器的行为,以便更容易地访问它们的实例。但是我想一次访问一个与每个类相关的实例,而不是所有实例都在同一个继承类中。在
实际上,再次编写代码有助于我理解我的问题:
a)Decorator的参数为somearg
b)下一行的内容(类A的定义)用作包装器函数的参数。在这个函数中我: 1) 记住初始类init以避免无限递归 2) 定义一个新的init以在实例级别进行更改 3) 为类绑定一个新的init方法 4) 返回转换后的类对象
c)因为返回是一个类对象,所以每次实例化一个实例时,我都直接转到init,因为这就是它在新类中的绑定方式。在
相关问题 更多 >
编程相关推荐