__new__ (双下划线)和_new_ (单下划线)有什么区别?我不能理解。
请看下面的代码。它使用双下划线__new__函数,但不起作用:
class B(object):
def __new__(cls,*a,**b):
ne = object.__new__(cls,*a,**b)
setattr(ne,"created at",datetime.datetime.now())
return ne
def __init__(self,x,y):
print("initteyiz")
self.x=x
self.y=y
h=B(1,2)
Traceback (most recent call last):
File "<pyshell#30>", line 1, in <module>
h=B(1,2)
File "<pyshell#29>", line 3, in __new__
ne = object.__new__(cls,*a,**b)
TypeError: object() takes no parameters但它使用单下划线_new_
class B(object):
def _new_(cls,*a,**b):
ne = object._new_(cls,*a,**b)
setattr(ne,"created at",datetime.datetime.now())
return ne
def __init__(self,x,y):
print("initteyiz")
self.x=x
self.y=y
e=B(1,2)
initteyiz
print(e)
<__main__.B object at 0x000000000337A518>为什么这是可行的?
发布于 2014-02-13 05:42:37
__new__是用于控制创建特定类的实例的Python special method。它在__init__之前调用,这是一种特殊的方法,用于控制该实例的初始化。
_new_只是一种普通的方法。下划线没有任何意义,除了该方法可能是私有的。PEP 8指出,在方法名之前加一个下划线意味着该方法将被当作私有方法使用(Python中没有真正私有的方法)。
考虑到以上几点,第一个示例产生的错误可以解释如下:
运行以下代码行时的
e=B(1,2)
在给定位置参数的情况下,隐式调用B.__new__,然后执行B.__new__中的1和2.
ne = object.__new__(cls,*a,**b)
此外,它试图将提供给B.__new__.
object.__new__的参数传递给object.__new__,除了cls之外,它不接受任何参数,这是对类B本身的引用。因此,将抛出TypeError。第二个示例没有抛出错误,因为如上所述,_new_只是一个普通的方法。因此,当您实例化类B时,它不会被隐式调用。
发布于 2014-02-13 05:58:23
在第一个示例中,您使用了特殊类型构造函数方法__new__,但错误地调用了基类型的__new__。基类型是object,object的类型构造函数本身不接受任何参数。但是将参数1和2传递给object.__new__。
如果你不传递这些参数,它就能正常工作:
class B(object):
def __new__(cls,*a,**b):
ne = object.__new__(cls) # <- here
setattr(ne,"created at",datetime.datetime.now())
return ne
def __init__(self,x,y):
print("initteyiz")
self.x=x
self.y=y在您的第二个示例中,您使用的是_new_,这只是一个普通的方法,所以没有什么奇特的事情发生。当然,它不会在对象构造时调用。
https://stackoverflow.com/questions/21740191
复制相似问题