代码之家  ›  专栏  ›  技术社区  ›  Data Mastery

理解/使用dict的初始方法

  •  0
  • Data Mastery  · 技术社区  · 3 年前

    我想到了如何使Python类可序列化的想法。

    class FileItem(dict):
        def __init__(self, name):
            dict.__init__(self, name=name)
    
    x = FileItem("test")
    print(x)
    
    {'name': 'test'}
    

    这很好,但我不明白怎么做。我想 dict.__init__ 呼叫 __init__ 方法来创建一个新实例,所以我希望它能起作用:

    x = dict.__init__(name="test")

    这会导致以下错误:

    TypeError: descriptor '__init__' of 'dict' object needs an argument

    为什么这与上面的例子不同?

    3 回复  |  直到 3 年前
        1
  •  1
  •   juanpa.arrivillaga    3 年前

    所以,请注意,您没有为 __init__ ,

    >>> x = dict.__init__(name="test")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: descriptor '__init__' of 'dict' object needs an argument
    

    它需要实例,即 self ,作为第一个论点。当然,如果你创建了一个合适的实例并传递了它, __初始化__ 返回 None :

    >>> x = dict.__init__({}, name="test")
    >>> print(x)
    None
    

    因为 __初始化__ 不是构造函数,而是初始值设定项。在Python中,这是对象初始化过程中的两个不同步骤。

    “构造函数”是 __new__

    >>> dict.__new__(dict)
    {}
    

    Read about it 在Python数据模型文档中。

    此外,为了体面起见,你可能不应该洒:

    x = dict.__new__(dict)
    

    真正的代码。但这就是它的工作原理。所有这些都发生在 type.__call__ 顺便说一句 type 是创建类的父类,一个元类。(它本身也是一种。。。 type(type) is type 就像 type(dict) is type ... )

    >>> type.__call__(dict)
    {}
    
        2
  •  1
  •   a_guest    3 年前

    __new__ 创建新实例,但 __init__ 用于初始化新创建的实例 __初始化__ 需要使用实例。

    当你这么做的时候 dict.__init__(name='test') 那么这在任何实例上都不起作用,因此出现了错误。具有 dict.__init__(self, name=name) 另一方面,您确实通过了实例 self 作为一个论点,因此它是有效的。

    通常你会使用 super().__init__(name=name) 它负责提供 自己 作为参数,并且在以后决定更改基类时也有效。

        3
  •  0
  •   Lukas Laudrain    3 年前

    区别在于 self 未通过的属性 __init__ 属性将其计算应用于实例( 自己 )如果 __初始化__ 函数没有任何上下文,它会抛出一个错误
    祝你今天愉快,卢卡斯。