在Python中,如何防止多次包含类定义?

时间:2012-12-17 13:49:44

标签: python class inheritance

我遇到了一个带有多个超类的子类调用其父 init 方法的问题。我收到一个错误,关于unbound __init__如何需要父实例,但得到了一个子实例。 StackOverflow上的其他一些问题指出,这是来自多次定义的父类,我用简单的脚本输入了解释器。

注意:这不是我问的问题的代码。这是一个示例,用于说明重新定义Base类的问题,并导致Inherited类不再正常运行。

>>> class Base(object):
...     def __init__(self):
...             print "Base!"
... 
>>> class Inherited(Base):
...     def __init__(self):
...             Base.__init__(self)
...             print "Inherited"
... 
>>> class Base(object):
...     def __init__(self):
...             print "Base!"
... 
>>> Inherited()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: unbound method __init__() must be called with Base instance as first argument (got Inherited instance instead)
>>> 

我的问题是,如何防止多次定义基类?我正在处理的项目有多个文件和导入,所以很难重构一切只是简单地包含文件。

2 个答案:

答案 0 :(得分:3)

这种行为对我来说似乎非常可疑。以不同方式导入相同的模块仍然会使您的类(Base)引用相同的类对象。您似乎不太可能通过导入进入这种情况。

但是,一种解决方法是使用super

class Base(object):
    def __init__(self):
            print "Base!"

class Inherited(Base):
    def __init__(self):
            super(Inherited,self).__init__()
            print "Inherited"

class Base(object):
    def __init__(self):
            print "Base!"

Inherited()

super确保您实际上正在调用基类__init__,而不是其他类恰好取代当前模块命名空间中基类的类。

答案 1 :(得分:3)

您在上面确定的问题是因为InheritedBase(您定义的第一个)的原始定义的子类,因为类定义在读取时被处理。

但是,在运行时,使用__init__第二个定义的Base。此类需要一个自身实例,而是接收Base的第一个定义的实例。

当您以这种方式键入内容时,解释器无法知道它们是同一个类。但是当从文件导入时,你不会遇到这个问题,因为Python足够聪明,知道当文件导入两次时,类是相同的。

您的代码还有其他功能,看看您的用例更具体,会很有帮助。只有在多个模块中定义具有相同名称的类,然后将它们导入到同一名称空间中时,才会出现此问题。