我正在尝试使用以下代码修饰一个实际的类:
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__()
的消息。
根据the docs for new-style classes:
典型的实现通过使用带有适当参数的
__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
答案 0 :(得分:11)
__init__
未运行,因为object.__new__
无法调用它。如果你改成它
cls.__call__(*args, **kwargs)
,或更好,cls(*args, **kwargs)
,它应该有用。请记住,类是可调用的:调用它会生成一个新实例。只是调用__new__
会返回一个实例,但不会进行初始化。另一种方法是调用__new__
,然后手动调用__init__
,但这只是替换__call__
中已经包含的逻辑。
您引用的文档是指在类的super
方法中从调用__new__
。在这里,你是从外面调用它,而不是像我已经讨论过的那样。
答案 1 :(得分: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"