【问题标题】:__new__ is not getting called in object creation__new__ 在对象创建中没有被调用
【发布时间】:2018-07-04 03:52:11
【问题描述】:

案例一:

class Person:
    def __new__(cls, *args, **kwargs):
        print "called"
        return super(Person, cls).__new__(cls, *args, **kwargs)

p=Person()

案例2:

class Person(object):
    def __new__(cls, *args, **kwargs):
        print "called"
        return super(Person, cls).__new__(cls, *args, **kwargs)

p=Person()

在第一种情况下,__new__() 方法不会被调用,但在第二种情况下会调用。

如果它没有被调用,那么Person 对象是如何创建的?

【问题讨论】:

  • 我 99.999% 确定你有这个倒退,__new__ 在第一种情况下 not 被调用,但 is 在第二。
  • 请参阅here 进行测试。
  • 无论如何:如果您还不了解旧式类,最简单的做法就是不要费心去学习它们,除非如何不意外地创建它们。这是过时的知识,不太可能对您有用。当然,如果您很好奇,或者如果您(或其他搜索此问题的人)碰巧遇到了需要使用旧式类的极少数情况之一,那么值得在 Stack Overflow 上获得答案。跨度>

标签: python class oop object python-2.x


【解决方案1】:

我猜这与 Python2 中的new and old style classes 有关:

旧式类实际上没有 __new__ 方法,因为对它们来说 __init__ 是构造函数,所以基本上如果我们有:

class A:

    def __new__(cls):
        print "A.__new__ is called"  # -> this is never called

A()

__new__ 的主体在这种情况下永远不会被执行,因为它不是旧式类的目的。

在 Python3 中,行为是相同的,无论是否显式继承 object 都没关系:

class Person1:
    def __new__(cls, *args, **kwargs):
        print("called")
        return super(Person1, cls).__new__(cls, *args, **kwargs)


class Person2(object):
    def __new__(cls, *args, **kwargs):
        print("called")
        return super(Person2, cls).__new__(cls, *args, **kwargs)


p1 = Person1()
p2 = Person2()

当从 3.x 调用时,这些应该打印两次“被调用”。

【讨论】:

  • 在 Python 3 中行为相同的原因是,无论你说与否,你总是继承自 object(这意味着没有旧式类)。
  • 无论如何,通常我会推荐一个文档链接,但是,AFAIK,唯一的文档是在“类类型”和“经典类”的standard type hierarchy 描述下,它是远未清楚。不过,(有些未完成/过时的)New-Style Classes 文档中可能有些内容。
  • @abarnert 是的,没错,3.x 中只有一种类型的类,这就是我的意思。
【解决方案2】:

我一直在寻找文档,终于在这里找到了: https://staging2.python.org/dev/peps/pep-0253/

类型对象有一个新槽,tp_new,它可以充当工厂 类型的实例。类型现在是可调用的,因为 tp_call slot 在 PyType_Type (元类型)中设置;该函数寻找 正在调用的类型的 tp_new 槽。

补充@devforfu 的答案,在过去,__new__ 不存在。它是通过添加新样式类添加的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-18
    • 2021-05-23
    • 1970-01-01
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 2012-09-21
    • 1970-01-01
    相关资源
    最近更新 更多