【问题标题】:Get attribute from a super class in python从python中的超类获取属性
【发布时间】:2015-08-10 15:56:25
【问题描述】:

我有一个基类,一堆子类,对于这些子类中的每一个,我都有另一组子子类。例如:

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

我需要获取SecondOrderSubClass__init__() 方法来进行以下赋值:self.lines = self.config_array

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

TypeError: __getattr__() takes exactly 1 argument (2 given)

【问题讨论】:

  • 你已经继承了属性,在FirstOrderSubClass中添加super(FirstOrderSubClass, self).__init__()

标签: python class oop inheritance subclass


【解决方案1】:

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

修复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__ unbound 方法(显式传入self)也可以:

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

请注意,如果您要让 FirstOrderSubClass.__init__ 做完全相同的事情,那么分配给 self.name 是没有意义的。

使用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

【讨论】:

  • 感谢您的解释!这正是我所缺少的。如果BaseClass.__init__ 没有运行,当然,我无法访问它!也非常感谢您指出演讲,几个月以来我一直在学习 Python,我正在尝试阅读/观看我发现的任何内容。
【解决方案2】:

你必须调用FirstOrderSubClasssuper方法:

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']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多