vko*_*kis 12 python methods object instances
我正在覆盖__new__()类的方法以返回具有特定__init__()集合的类实例.Python似乎调用类提供的__init__()方法而不是特定于实例的方法,尽管Python文档在
http://docs.python.org/reference/datamodel.html
说:
典型的实现通过使用带有适当参数的super(currentclass,cls).__ new __(cls [,...])调用超类的__new __()方法创建类的新实例,然后在返回之前根据需要修改新创建的实例它.
如果__new __()返回一个cls实例,那么新实例的__init __()方法将被调用,如__init __(self [,...]),其中self是新实例,其余参数与传递给的相同. __新__().
这是我的测试代码:
#!/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()
Run Code Online (Sandbox Code Playgroud)
哪个输出
$ 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 = {}
Run Code Online (Sandbox Code Playgroud)
似乎唯一myinit()可以运行的方法是将其明确地称为self.__init__()内部myclass.__init__().
Sve*_*ach 10
关于新样式类的特殊方法是在实例的类型上查找,而不是在实例本身上查找.这是记录在案的行为:
对于新式类,只有在对象的类型上定义,而不是在对象的实例字典中,才能保证对特殊方法的隐式调用才能正常工作.这种行为是以下代码引发异常的原因(与旧式类的等效示例不同):
>>> 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()
Run Code Online (Sandbox Code Playgroud)
总是通过类而不是实例访问各种特殊方法(包括__init__,还包括运算符重载__add__等).不仅如此,它们不能通过类或元类的方法或方法访问,它们必须直接在类上.这是出于效率的原因:__getattr____getattribute__
__getattribute__()以这种方式绕过机器为解释器内的速度优化提供了很大的空间,代价是处理特殊方法的一些灵活性(必须在类对象本身上设置特殊方法以便由解释器一致地调用) .
你要完成的是什么并不完全清楚,但你可以做的一件事是myclass在__new__方法中进行子类化:
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)
Run Code Online (Sandbox Code Playgroud)