从python中的超类获取属性

时间:2015-05-28 08:47:37

标签: python class oop inheritance 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

我需要获取__init__()的{​​{1}}方法进行以下分配:SecondOrderSubClass

编辑:添加了行self.lines = self.config_array。如果我运行代码,我得到:

print self.config_array

2 个答案:

答案 0 :(得分:5)

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

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

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

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

但是,您的__init__方法签名不匹配,因此您不能依赖此处的合作行为;只要在层次结构中添加混合类,事情就可能并且可能会中断。请参阅Raymond Hettinger撰写的*Python's super() is considered super!或其后续工作PyCon presentation,以解释您希望签名与之匹配的原因。

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

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

请注意,如果您要求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

答案 1 :(得分:1)

您必须调用FirstOrderSubClass super方法:

class BaseClass(object):
    def __init__(self):
        with open("config.example.txt",'w') as f:
            f.write("Hello world")
        with open("config.example.txt") as f:
            self.config_array = f.readlines()

class FirstOrderSubClass(BaseClass):
    def __init__(self, name):
        super(FirstOrderSubClass,self).__init__()
        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

grandchild = SecondOrderSubClass("peter",2.0)
print grandchild.config_array
##>>> 
##['Hello world']