将参数传递给基类构造函数还是使用实例变量?

10

所有派生自某个基类的类都必须定义一个名为“path”的属性。 就鸭子类型而言,我可以依靠子类中的定义:

class Base:
    pass # no "path" variable here

def Sub(Base):
    def __init__(self):
        self.path = "something/"

另一个可能的方法是使用基类构造函数:

class Base:
    def __init__(self, path):
        self.path = path

def Sub(Base):
    def __init__(self):
        super().__init__("something/")

我使用的是Python 3.1。

你更喜欢哪个版本,为什么?有更好的方法吗?

1个回答

14
Python 3.0+:
To ensure that derived classes provide the necessary path property, it's recommended to use a parameter in the base class's constructor like in the second example. This approach documents that the class has such a property and requires derived classes to provide it. Otherwise, you would need to rely on this information being stated in the class's docstrings, although it's still helpful to explain what the property means. Python 2.6+:
Neither of the above approaches is recommended. Instead, consider using a different method.
class Base(object):
    def __init__(self,path):
        self.path=path;

class Sub(Base):
    def __init__(self):
       Base.__init__(self,"something/")
换句话说,我需要在基类的构造函数中使用这样的参数,因为它记录了所有这些类型将具有/使用/需要该特定参数,并且需要提供该参数。但是,我不会使用super(),因为在Python中super有些脆弱和危险,并且我还会通过继承自object(或其他新式类)类使Base成为新式类

5
super()并不脆弱,2.x语法存在脆弱性,在3.x中已经修复(正如OP使用的那样,由super()调用),以及多重继承一般也存在脆弱性。在Python 3.x中,没有任何理由直接调用基类方法,super().__init__(...)语法从未更差,通常更好。 - Thomas Wouters
从使用 super 的情况来看,我猜 deamon 正在使用 py3k。 - SilentGhost
@Thomas Wouters:如果你使用多重继承和具有不同构造函数签名的基类,你会如何使用super?将所有派生类的参数都传递给所有基类看起来很糟糕,依赖于命名参数并让基类自行排序也不是很好。 - kriss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接