Why doesn't Python call instance method __init__() on instance creation but calls class-provided __init__() instead?
我重写了类的
http://docs.python.org/reference/datamodel.html网站
说:
Typical implementations create a new instance of the class by invoking the
superclass’s __new__() method using super(currentclass, cls).__new__(cls[, ...])
with appropriate arguments and then modifying the newly-created instance as
necessary before returning it.If __new__() returns an instance of cls, then the new instance’s __init__() method
will be invoked like __init__(self[, ...]), where self is the new instance and the
remaining arguments are the same as were passed to __new__().
这是我的测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #!/usr/bin/env python import new def myinit(self, *args, **kwargs): print"myinit called, args = %s, kwargs = %s" % (args, kwargs) class myclass(object): def __new__(cls, *args, **kwargs): ret = object.__new__(cls) ret.__init__ = new.instancemethod(myinit, ret, cls) return ret def __init__(self, *args, **kwargs): print"myclass.__init__ called, self.__init__ is %s" % self.__init__ self.__init__(*args, **kwargs) a = myclass() |
哪些输出
1 2 3 4 5 | $ python --version Python 2.6.6 $ ./mytest.py myclass.__init__ called, self.__init__ is <bound method myclass.myinit of <__main__.myclass object at 0x7fa72155c790>> myinit called, args = (), kwargs = {} |
看来让
新样式类上的特殊方法是在实例的类型上查找的,而不是在实例本身上查找的。这是记录在案的行为:
For new-style classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary. That behaviour is the reason why the following code raises an exception (unlike the equivalent example with old-style classes):
1 2 3 4 5 6 7 8 9 | >>> class C(object): ... pass ... >>> c = C() >>> c.__len__ = lambda: 5 >>> len(c) Traceback (most recent call last): File"<stdin>", line 1, in <module> TypeError: object of type 'C' has no len() |
各种特殊方法(包括
Bypassing the
__getattribute__() machinery in this fashion provides significant scope for speed optimisations within the interpreter, at the cost of some flexibility in the handling of special methods (the special method must be set on the class object itself in order to be consistently invoked by the interpreter).
目前还不完全清楚您试图完成什么,但您可以在这里做的一件事是在
1 2 3 4 5 6 7 | class myclass(object): def __new__(cls, *args, **kwargs): class subcls(cls): def __new__(cls, *args, **kwargs): return object.__new__(cls) subcls.__init__ = myinit return subcls(*args, **kwargs) |