【问题标题】:Python: How to understand __new__ as defined in the built-in object class?Python:如何理解内置对象类中定义的 __new__?
【发布时间】:2019-06-05 03:40:12
【问题描述】:

首先,这不是Why is __init__ not called after __new__ SOMETIMES 的重复,因为这个问题实际上是关于内置object 类的实现。

这是完整的故事:

我正在学习 Python 中的 __new____init__。这是我尝试过的示例:

class A(object):

    def __new__(cls):
        print("A.__new__ called")
        return super(A, cls).__new__(cls)

    def __init__(self):
        print("A.__init__ called")

A()
print('finished')

输出是

A.__new__ called
A.__init__ called
finished

我知道__new__ 进行对象创建,__init__ 进行对象初始化。

__new__ 在调用类名时自动调用。然后每次__new__返回类的实例时调用__init__,将返回的实例作为self参数传递给__init__

知道了这一点,如果我们有一个错误的 __new__ 函数,它不会创建并返回一个对象实例,那么 __init__ 就不会被调用:

class A(object):

    def __new__(cls):
        print("A.__new__ called")
        #return super(A, cls).__new__(cls)

    def __init__(self):
        print("A.__init__ called")

A()

注意__new__ 方法只打印一个字符串。它不返回任何东西,所以__init__ 没有什么可取的。事实上,输出证实了这一点:

A.__new__ called
finished

"A.__init__ called" 永远不会被打印出来,所以__init__ 确实永远不会被调用。

现在如果我们不定义__new__方法(这是99%的常见用例。程序员很少需要定义这个方法),那么默认调用父亲的__new__。例如

class A(object):

    def __init__(self):
        print("A.__init__ called")

A()
print('finished')

输出是:

A.__init__ called
finished

在这种情况下,内置object 类的__new__ 被调用。

但是,当我查看内置 object 类的定义方式时,我看到了:

class object:
    """ The most base type """
    def __delattr__(self, *args, **kwargs): # real signature unknown
        """ Implement delattr(self, name). """
        pass
    ...
    ...
    ...

     @staticmethod # known case of __new__
     def __new__(cls, *more): # known special case of object.__new__
         """ Create and return a new object.  See help(type) for accurate signature. """
         pass

没有在__new__ 中实现!里面只有一个pass !!??

这有什么意义?

【问题讨论】:

  • 这不是实际的实现。看起来这些只是签名的存根。这是pycharm吗?
  • @MSeifert 是的,这是 pycharm。你知道我在哪里可以找到实际的实现吗?
  • @MadisonCourto 这个问题怎么重复?

标签: python class object pycharm instantiation


【解决方案1】:

一些 Cpython 实现是用 C 编写的,因此 PyCharm 无法导航到源代码,因为它已编译。但是,它可以并且确实显示模拟签名的存根。

3.7.3 的 object.__new__ 的源代码可以在他们的 Github 存储库中找到:https://github.com/python/cpython/blob/v3.7.3/Objects/typeobject.c#L3671-L3732

【讨论】:

  • 谢谢。这很有帮助。我想我已经挖得够深了,到了我不能再继续挖的程度了。 (除非我有时间全面了解 C 并通读 C 实现)。
猜你喜欢
  • 1970-01-01
  • 2020-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-18
  • 2015-10-08
  • 1970-01-01
  • 2012-09-21
相关资源
最近更新 更多