从python中的超类获取属性

raf*_*ffo 2 python oop inheritance class subclass

我有一个基类,一堆子类,对于每个子类,我有另一组子类.例如:

class BaseClass(object):
    def __init__(self):
        with open(config.txt) as f
            self.config_array = f.readlines()

class FirstOrderSubClass(BaseClass):
    def __init__(self, name):
        self.name = name

class SecondOrderSubClass(FirstOrderSubClass):
    def __init__(self, name, version):
        self.name = name
        self.version = version
        super(SecondOrderSubClass, self).__init__(self.name)
        # needed to access self.config_array
        print self.config_array
Run Code Online (Sandbox Code Playgroud)

我需要得到__init__()的方法SecondOrderSubClass作如下分配:self.lines = self.config_array.

编辑:添加行print self.config_array.如果我运行代码我得到:

TypeError: __getattr__() takes exactly 1 argument (2 given)
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 5

在运行设置属性self.config_array之前,您无法访问BaseClass.__init__().

修复FirstOrderSubClass以调用基类__init__或直接调用它.

修复FirstOrderSubClass它可能是最好的方法:

class FirstOrderSubClass(BaseClass):
    def __init__(self, name):
        super(FirstOrderSubClass, self).__init__()
        self.name = name
Run Code Online (Sandbox Code Playgroud)

但是,您的__init__方法签名不匹配,因此您不能依赖合作行为; 只要在层次结构中添加混合类,事情就可能并且可能会中断.看*Python super()被认为超级!作者:Raymond Hettinger,或者它的后续PyCon演示文稿解释了为什么你希望你的签名匹配.

BaseClass.__init__直接调用未绑定方法(self显式传入)也可以:

class SecondOrderSubClass(FirstOrderSubClass):
    def __init__(self, name, version):
        super(SecondOrderSubClass, self).__init__(name)
        self.version = version
        BaseClass.__init__(self)
Run Code Online (Sandbox Code Playgroud)

请注意,self.name如果您要求FirstOrderSubClass.__init__完成相同的操作,那么分配到那里是没有意义的.

正确的使用super()方法是让所有方法至少接受所有相同的参数.由于object.__init__()从来不做,这意味着你需要不使用定点类super(); BaseClass会在这里做得很好.您可以使用*args**kw捕获任何其他参数,并忽略那些以使合作子类化工作:

class BaseClass(object):
    def __init__(self, *args, **kw):
        with open(config.txt) as f
            self.config_array = f.readlines()

class FirstOrderSubClass(BaseClass):
    def __init__(self, name, *args, **kw):
        super(FirstOrderSubClass, self).__init__(*args, **kw)
        self.name = name

class SecondOrderSubClass(FirstOrderSubClass):
    def __init__(self, name, version, *args, **kw):
        super(SecondOrderSubClass, self).__init__(name, *args, **kw)
        self.version = version
Run Code Online (Sandbox Code Playgroud)