【问题标题】:What is the purpose of calling __init__ directly?直接调用 __init__ 的目的是什么?
【发布时间】:2013-04-21 00:27:16
【问题描述】:

我很难弄清楚我遇到的一些代码的用途。

代码有一个类Foo,它有一个__init__ 方法,它接受多个参数。根据我目前对 Python 的了解,通过调用Foo('bar'),它会将此字符串作为参数传递给__init__(我认为它应该相当于构造函数)。

但我遇到的问题是我正在查看的代码是直接调用Foo.__init__('bar')。这样做的目的是什么?我几乎觉得我在__init__ 背后缺少了一些其他的目的。

【问题讨论】:

    标签: python init


    【解决方案1】:

    当你实例化一个类时,__init__() 方法会被调用。但是,父类中的__init__()方法不会被自动调用,所以如果你想扩展它的功能需要你直接调用它:

    class A:
    
         def __init__(self, x):
              self.x = x
    
    class B(A):
    
         def __init__(self, x, y):
              A.__init__(self, x)
              self.y = y
    

    注意,上面的调用也可以写成super:

    class B(A):
    
         def __init__(self, x, y):
              super().__init__(x)
              self.y = y
    

    __init__() 方法的目的是初始化类。它通常负责填充实例变量。因此,您希望为类层次结构中的所有类调用 __init__()。

    【讨论】:

    • 在第二个示例代码块中,为什么在B构造函数中调用super().__init__(x)而不是调用(super())(x)?也许这是一个单独的问题,但为什么 __init__ 调用不将 B 的 self 作为其第一个参数?只有当您需要传递一些东西以用作对实例的引用时,才需要调用__init__ 吗?
    【解决方案2】:

    Python 允许您直接调用构造函数 (__init__)。通过调用Foo.__init__(obj, 'bar'),您正在对obj 进行初始化/重新初始化

    查看此代码:

    class Foo:
        def __init__(self, s):
            self.s = s
    
    f = Foo('abc')
    print(f.s) # prints 'abc'
    Foo.__init__(f, 'def')
    print(f.s) # prints 'def'
    

    【讨论】:

    • 天哪。请不要致电__init__ 在任何健全的系统中执行重新初始化...
    • 我同意。对不起,如果我的解释不好。现在我只想展示__init__ 做了什么。不是应该调用它的地方。
    • 说“__init__ 并不是一个真正的构造函数,而是一个初始化”是没有帮助的。这是有人曾经在一本书中写过的东西,它已经在整个互联网上重复出现,尽管它没有任何意义,只会让那些已经知道什么是构造函数并且正在学习 Python 的人感到困惑。 __init__ 完全对应其他语言的构造函数,Python 官方文档甚至将其称为一个!如果您可以使用任何其他 OO 语言在现有对象上调用构造函数,这正是它会做的事情。
    • 我创建了这个主题的第一个答案,它很好地恢复了我想要告诉的内容:stackoverflow.com/questions/6578487/init-as-a-constructor。此外,__init__ 并不“完全对应于其他语言的构造函数”,因为您无法用其他语言(c、c++、Java 中的 AFAIK)编写我上面写的内容。我想说的是__init__ 不像在其他语言中那样创建新对象,我认为了解这一点对理解元类很有用。但是我知道 __init__ 不应该像我在之前的评论中所说的那样被调用。
    • @segfolt Java 和 C++ 构造函数也不创建新对象。当构造函数被调用时,对象已经被创建(我不记得在构造函数中写过类似this = malloc(...) 的东西;你呢?)。 __init__ 的目的是操作 对“空白”对象以初始化其中包含的数据,并且当您调用 SomeClass(...) 时,对象创建机制会自动调用它 对象创建之后,SomeClass(...) 表达式将其值返回给调用者之前。对我来说听起来就像一个 Java/C++ 构造函数......
    【解决方案3】:

    是 - 当继承类调用父类的__init__() 时。 AFAIK,这是明确调用__init__() 的唯一有效情况。

    【讨论】:

      猜你喜欢
      • 2013-05-08
      • 2021-06-08
      • 2019-03-17
      • 1970-01-01
      • 1970-01-01
      • 2010-10-15
      相关资源
      最近更新 更多