为了账号安全,请及时绑定邮箱和手机立即绑定

Python 3 中默认的 ```__new__``` 是什么?

Python 3 中默认的 ```__new__``` 是什么?

阿晨1998 2022-04-27 16:21:05
我相信我对应该做什么有一定的了解__new__(创建一个类的实例,但不初始化它,这是 的工作__init__)。但是,我想了解 Python 3__new__默认作为方法实现的内容。我也觉得它cls的一个参数有点令人困惑__new__,但__new__它是一个静态方法而不是一个类方法(我从文档中得到这个)......现在它是如何作为它的第一个参数传递一个类型的?
查看完整描述

2 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

第一部分:__new__默认情况下做什么?因为从头开始创建对象是一项基本的、特定于实现的操作,所以定义object.__new__(与 定义的其余部分一样)必然object是实现本身的一部分。这意味着您需要查看 CPython、PyPy、Cython 等的源代码,以准确了解在 Python 的任何特定实现中如何管理对象创建。通常,这都是无法从 Python 本身直接访问的低级簿记。


第二部分:如何__new__知道它得到了一个类参数?因为它假设它的第一个参数是一个类,如果调用者希望__new__正确工作,最好提供一个类!也就是说,没有人真正明确地调用__new__过,除了通过super覆盖__new__,然后,您必须确保cls自己明确地传递:


def __new__(cls, *args, **kwargs):

    rv = super().__new__(cls, *args, **kwargs)  # Not super().__new__(*args, **kwargs)

Foo其余时间,您不是通过Foo.__new__(Foo, ...)直接调用,而是通过调用类型本身来创建类的实例: Foo(...). 这是管理的,因为 's 元类的__call__方法Foo负责调用__new__你的。例如,您可以想象type.__call__大致定义为


# A regular instance method of type; we use cls instead of self to

# emphasize that an instance of a metaclass is a class

def __call__(cls, *args, **kwargs):

    rv = cls.__new__(cls, *args, **kwargs)  # Because __new__ is static!

    if isinstance(rv, cls):

        rv.__init__(*args, **kwargs)

    return rv

请注意,__init__只有在__new__实际返回__new__首先调用的类的实例时才会调用。


查看完整回答
反对 回复 2022-04-27
?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

根据我的理解,默认实现__new__()是这样的


class Default(object):

def __new__(cls, *args, **kwargs):

    print("In new")

    return super().__new__(cls,*args, **kwargs)


def __init__(self):

    print("In init default")


default = Default()

print(type(default))

输出


In new

In init default

<class '__main__.Default'>

基于文档 https://docs.python.org/3/reference/datamodel.html#object。新的


典型的实现通过使用 super() 调用超类的__new__()方法来创建类的新实例。new (cls[, ...]) 带有适当的参数,然后在返回之前根据需要修改新创建的实例。


该super().__new__()调用将创建实例并__init__()进行初始化。


下面的代码显示了不正确的覆盖__new__()


class InccorectOverride(object):


def __new__(cls, *args, **kwargs):

    pass


def __init__(self):

    print("In init InccorectOverride")


a = InccorectOverride()

print(type(a))

输出


<class 'NoneType'>

由于__new__()不返回实例,因此输出值为 NoneType


希望这能回答你的问题


查看完整回答
反对 回复 2022-04-27
  • 2 回答
  • 0 关注
  • 229 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号