为什么';t Python在创建实例时调用实例方法uuu init uuuu(),但调用提供的类uuu init uuuu()?

为什么';t Python在创建实例时调用实例方法uuu init uuuu(),但调用提供的类uuu init uuuu()?,python,object,methods,instances,Python,Object,Methods,Instances,我正在超越类的\uuuunew\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。Python似乎调用了提供的类\uuuu init\uuu()方法,而不是特定于实例的方法,尽管 说: 典型的实现通过调用 使用super(currentclass,cls)的超类的uuuu new_uuu()方法 使用适当的参数,然后将新创建的实例修改为 在归还之前需要 如果u

我正在超越类的
\uuuunew\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。Python似乎调用了提供的类
\uuuu init\uuu()
方法,而不是特定于实例的方法,尽管

说:

典型的实现通过调用 使用super(currentclass,cls)的超类的uuuu new_uuu()方法 使用适当的参数,然后将新创建的实例修改为 在归还之前需要

如果uuuuuuuuuuuuuuuuuuu()返回cls的实例,则新实例的uuuuu init_uuuuuuu()方法 将像uuu init(self[,…])一样调用,其中self是新实例,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 = {}
$python--版本
Python 2.6.6
$./mytest.py
myclass.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
调用myinit,args=(),kwargs={}
运行
myinit()
的唯一方法似乎是显式地将其称为
self。
myclass中的
各种特殊方法(包括
\uuu init\uuuuuu
,但也包括
\uu add\uuuuu
等运算符重载)都是可用的。不仅如此,它们还不能通过类或元类上的
\uuuu getattr\uuuuuuuu
\uuuuuuu getattribute\uuuuuuuu
方法访问,它们必须直接位于类上。这是为了提高效率:

以这种方式绕过
\uuuu getattribute\uuuu()
机器,为解释器内的速度优化提供了很大的空间,但代价是在处理特殊方法时有一定的灵活性(必须在类对象本身上设置特殊方法,以便解释器一致地调用)

现在还不完全清楚您想要完成什么,但您可以在这里做的一件事是在
\uuuu new\uuu
方法中对
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)

新样式类上的特殊方法是在实例的类型上查找的,而不是在实例本身上查找的。这是:

对于新样式的类,只有在对象的类型上定义了特殊方法的隐式调用,而不是在对象的实例字典中定义了特殊方法的隐式调用,才能保证其正常工作。这种行为是以下代码引发异常的原因(与旧式类的等效示例不同):

>>C类(对象):
...     通过
...
>>>c=c()
>>>c.。__len__;=λ:5
>>>莱恩(c)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:类型“C”的对象没有len()
为什么Python在创建实例时不调用实例方法init(),而是调用提供的类init()

看看这个例子

class C:
   one = 42
   def __init__(self,val):
        self.two=val
ci=C(50)
print(ci.__dict__)
print(C.__dict__)

结果如下:

{'two': 50}
{'__module__': '__main__', 'one': 42, '__init__': <function C.__init__ at 0x00000213069BF6A8>, '__dict__': <attribute '__dict__' of 'C' objects>, '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None}
{'two':50}
{“模块”:“主模块”:“一”:42,“初始模块”:“指令模块”:“weakref”:“无”
请注意,只有值
{'two':50}
是实例dict的一部分

'one':42
属于一个类
C
dict。
\uuuu init\uuu
方法也是如此

这是每种设计

{'two': 50}
{'__module__': '__main__', 'one': 42, '__init__': <function C.__init__ at 0x00000213069BF6A8>, '__dict__': <attribute '__dict__' of 'C' objects>, '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None}