Python中对象的__init__()方法有什么作用?

24 投票
3 回答
27884 浏览
提问于 2025-04-17 08:53

在阅读OpenStack的代码时,我遇到了这样一个情况。

有一个叫做'Service'的类,它继承了一个基础类'object',然后在Service的__init__()方法中,调用了对象的__init__方法。相关的代码看起来是这样的:

类的定义:

class Service(object):

还有Service的初始化方法定义:

def __init__(self, host, binary, topic, manager, report_interval=None,
             periodic_interval=None, *args, **kwargs):

在Service的初始化方法中调用了super(这里的'object'):

super(Service, self).__init__(*args, **kwargs)

我不太明白最后这个调用,object.__init__()到底是干什么的?有没有人能帮我解释一下?

3 个回答

1

object.__init__() 实际上并没有做什么,但即使一个类只有 object 作为父类,super() 的调用也应该包含在内。

一个关于 'super' 的大问题是,它听起来像是会调用父类的方法的副本。其实并不是这样,它会调用方法解析顺序(MRO)中的下一个方法 (...) 有些人会省略对 initsuper(...) 调用,因为如果唯一的父类是 'object',那么 object.init 并没有做什么!然而,这样做是非常错误的。这样会导致其他类的 init 方法不会被调用。

http://fuhm.net/super-harmful/

3

super() 并不总是返回父类的代理。 实际上,它返回的是 下一个类在 方法解析顺序(MRO) 中的代理。在单继承的情况下,MRO和继承链没有区别。但在多继承的情况下,MRO可能会返回一个在 另一条 继承链上的类。

16

简单来说,object.__init__() 方法除了检查是否传入了参数外,实际上什么都不做。想了解更多细节,可以查看这个链接

当在 Service 的实例上调用 super() 时,它会转到 object.__init__(),结果就是没有任何操作。

不过,当在 Service 的子类实例上调用时,事情就变得有趣了。super() 调用可能会转到一个不同于 object 的类,这个类是实例的父类,但不是 Service 的父类。想了解这个是怎么回事以及为什么有用,可以看看这篇博客 Python's Super Considered Super

下面这个例子(有点牵强)展示了 Service 的子类如何让 Service 中的 super 调用指向另一个叫 Color 的类:

class Service(object):
    def __init__(self, host, binary, topic, manager, report_interval=None,
             periodic_interval=None, *args, **kwargs):
        print 'Initializing Service'
        super(Service, self).__init__(*args, **kwargs)

class Color(object):
    def __init__(self, color='red', **kwargs):
        print 'Initializing Color'
        self.color = color
        super(Color, self).__init__(**kwargs)

class ColoredService(Service, Color):
    def __init__(self, *args, **kwds):
        print 'Initializing Colored Service'
        super(ColoredService, self).__init__(*args, **kwds)

c = ColoredService('host', 'bin', 'top', 'mgr', 'ivl', color='blue')

在这个例子中,初始化的顺序是:

  1. 初始化 Colored Service
  2. 初始化 Service
  3. 初始化 Color
  4. 初始化 object -- 只做参数检查,不做其他操作

撰写回答