Python 类装饰器
我正在尝试装饰一个实际的类,使用了以下代码:
def my_decorator(cls):
def wrap(*args, **kw):
return object.__new__(cls)
return wrap
@my_decorator
class TestClass(object):
def __init__(self):
print "__init__ should run if object.__new__ correctly returns an instance of cls"
test = TestClass() # shouldn't TestClass.__init__() be run here?
虽然没有错误,但我也没有看到来自 TestClass.__init__()
的消息。
根据新式类的文档:
通常的实现是通过调用父类的
__new__()
方法来创建类的新实例,使用super(currentclass, cls).__new__(cls[, ...])
并传入适当的参数,然后在返回之前根据需要修改新创建的实例。如果
__new__()
返回的是 cls 的一个实例,那么新实例的__init__()
方法会被调用,像这样__init__(self[, ...])
,其中 self 是新实例,剩下的参数和传给__new__()
的参数是一样的。
你知道为什么 __init__
没有运行吗?
另外,我尝试像这样调用 __new__
:
return super(cls.__bases__[0], cls).__new__(cls)
但它会返回一个 TypeError
:
TypeError: super.__new__(TestClass): TestClass is not a subtype of super
2 个回答
0
我也说不清楚具体原因,但这个小技巧确实能让 __init__
这个方法运行起来。
def my_decorator(cls):
print "In my_decorator()"
def wrap(*args, **kw):
print "In wrap()"
return cls.__init__(object.__new__(cls), *args, **kw)
return wrap
@my_decorator
class TestClass(object):
def __init__(self):
print "__init__ should run if object.__new__ correctly returns an instance of cls"
10
__init__
方法没有被执行,因为 object.__new__
并不知道要去调用它。如果你把它改成 cls.__call__(*args, **kwargs)
,或者更好的是 cls(*args, **kwargs)
,这样就可以正常工作了。记住,类是可以被调用的:调用一个类会产生一个新的实例。单单调用 __new__
只是返回一个实例,但并没有进行初始化。另一种方法是先调用 __new__
,然后手动调用 __init__
,但这其实只是替代了已经在 __call__
中实现的逻辑。
你引用的文档是指在类的 __new__
方法内部调用 super
。而在这里,你是从外部调用它,并不是我之前讨论的那种常规方式。