从python中的超类获取属性 [英] Get attribute from a super class in python

查看:88
本文介绍了从python中的超类获取属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a base class, a bunch of subclasses, and for each of these subclasses, I have another set of sub-subclasses. For example:

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.

I need to get the __init__() method of the SecondOrderSubClass to make the following assignment: self.lines = self.config_array.

添加了行print self.config_array.如果我运行代码,我将得到:

added line print self.config_array. If I run the code I get:

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

推荐答案

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

You cannot access self.config_array until BaseClass.__init__() has run to set the attribute.

要么修复FirstOrderSubClass,要么也调用基类__init__或直接调用它.

Either fix FirstOrderSubClass to also invoke the base class __init__ or call it directly.

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

Fixing the FirstOrderSubClass is probably the best way to do so:

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

但是,您的__init__方法签名不匹配,因此您不能在这里依靠合作行为.在层次结构中添加混合类后,事情就可能并且很可能会中断.参见 * Python的super()被认为是超级!由Raymond Hettinger撰写,或者是其后续操作 PyCon演示来解释为什么您希望签名匹配

However, your __init__ method signatures do not match so you cannot rely on cooperative behaviour here; as soon as you add a mix-in class in the hierarchy, things can and probably will break. See *Python's super() is considered super! by Raymond Hettinger, or it's followup PyCon presentation to explain why you want your signatures to match.

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

Calling the BaseClass.__init__ unbound method directly (passing in self explicitly) would also work:

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

请注意,如果您要让FirstOrderSubClass.__init__做完全相同的事情,则没有必要分配给self.name.

Note that there is no point in assigning to self.name there if you are going to ask FirstOrderSubClass.__init__ to do the exact same thing.

使用super()的正确方法是让您的所有方法至少接受所有相同的参数.由于object.__init__()从不执行,这意味着您需要一个不使用super()的哨兵类. BaseClass在这里会很好.您可以使用*args**kw捕获任何其他参数,而忽略它们以使协作子类化起作用:

The proper way to use super() is for all your methods to at least accept all the same arguments. Since object.__init__() never does, this means you need a sentinel class that does not use super(); BaseClass will do nicely here. You can use *args and **kw to capture any additional arguments and just ignore those to make cooperative subclassing work:

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

这篇关于从python中的超类获取属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆