为什么Python不调用实例方法__init __()创建实例,而是调用类提供的__init __()来代替?
我在覆盖__new__()
方法返回一个具有特定__init__()
集合的类实例。蟒蛇似乎在为什么Python不调用实例方法__init __()创建实例,而是调用类提供的__init __()来代替?
http://docs.python.org/reference/datamodel.html
调用这个类提供的__init__()
方法,而不是特定实例的方法,虽然Python的文件说:
典型实现创建由类的新实例使用super(currentclass,cls).__ new __(cls [,...]) 调用 超类的__new __()方法,然后在返回它之前修改新创建的实例为 。
如果__new __()返回CLS的实例,那么新实例的__init __()方法 将被调用像__init __(自我[,...]),其中self是新实例,其余的 论据和传递给__new __()一样。
这里是我的测试代码:
#!/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()
其输出
$ 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 = {}
,似乎只有这样才能获得myinit()
运行,是显式调用它self.__init__()
内myclass.__init__()
。
新样式类特殊的方法是看取决于实例的类型,而不是实例本身。这是documented behaviour:
对于新样式类,特殊的方法调用隐含只能保证,如果一个对象的类型定义,而不是在对象的实例字典才能正常工作。这种行为就是为什么下面的代码会引发异常(不像相当于例如使用老式类)的原因:
>>> 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()
各种特殊方法(包括__init__
,还有运营商过载如__add__
等)都是always accessed via the class rather than the instance。不仅如此,它们不能通过类或元类上的__getattr__
或__getattribute__
方法访问,它们必须直接在类上。这是出于效率的原因:
绕过以这种方式
__getattribute__()
机械提供显著范围为解释器内的速度最佳化,以在特殊的方法处理的一些灵活性为代价的(特殊的方法必须设置上类对象本身为了一致地被解释器调用)。
这不是完全清楚你要完成什么,但有一点你可以在这里做的是对__new__
方法中继承myclass
:
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)
大问题! – Marcin 2012-07-24 16:49:29