首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >new: differents __new__和_new_的类型错误

new: differents __new__和_new_的类型错误
EN

Stack Overflow用户
提问于 2014-02-13 05:35:08
回答 2查看 82关注 0票数 0

__new__ (双下划线)和_new_ (单下划线)有什么区别?我不能理解。

请看下面的代码。它使用双下划线__new__函数,但不起作用:

代码语言:javascript
运行
复制
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_

代码语言:javascript
运行
复制
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>

为什么这是可行的?

EN

回答 2

Stack Overflow用户

发布于 2014-02-13 05:42:37

__new__是用于控制创建特定类的实例的Python special method。它在__init__之前调用,这是一种特殊的方法,用于控制该实例的初始化。

_new_只是一种普通的方法。下划线没有任何意义,除了该方法可能是私有的。PEP 8指出,在方法名之前加一个下划线意味着该方法将被当作私有方法使用(Python中没有真正私有的方法)。

考虑到以上几点,第一个示例产生的错误可以解释如下:

运行以下代码行时的

e=B(1,2)

在给定位置参数的情况下,隐式调用B.__new__,然后执行B.__new__中的12.

  • This行:

ne = object.__new__(cls,*a,**b)

此外,它试图将提供给B.__new__.

  • object.__new__的参数传递给object.__new__,除了cls之外,它不接受任何参数,这是对类B本身的引用。因此,将抛出TypeError

第二个示例没有抛出错误,因为如上所述,_new_只是一个普通的方法。因此,当您实例化类B时,它不会被隐式调用。

票数 3
EN

Stack Overflow用户

发布于 2014-02-13 05:58:23

在第一个示例中,您使用了特殊类型构造函数方法__new__,但错误地调用了基类型的__new__。基类型是objectobject的类型构造函数本身不接受任何参数。但是将参数12传递给object.__new__

如果你不传递这些参数,它就能正常工作:

代码语言:javascript
运行
复制
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_,这只是一个普通的方法,所以没有什么奇特的事情发生。当然,它不会在对象构造时调用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21740191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档