猿问

Python 循环遍历基类中的非继承属性

我有一个包含数字属性的基类,这些属性在初始化时作为字典简单地传递给它,然后添加到实例的字典中:


class baseclass(object):

    def __init__(self, **kwargs):

        self.__dict__.update(kwargs)


    def calcValue(self):

        return sum(vars(self).values())

现在我有一个从这个类派生的类,它为类添加了额外的属性,例如;


class childclass(baseclass):

    def __init__(self, stringValue, **kwargs):

        super(childclass, self).__init__(kwargs)

        self.name = stringValue

现在我想在我的基类中有一个函数,它只迭代添加到类中的所有属性,而不是作为子属性添加的属性。例如,如果我创建一个这样的子类实例:


instance = childclass("myname", a=1, b=2, c=3)

然后调用 calcValue 方法,它应该返回 1+2+3 = 6


instance.calcValue()

但是因为 vars(self) 将返回完整的字典,不包括来自 childclass 属性的字符串,当然不能添加。有没有办法只访问属于各自派生类的实例的属性?


红颜莎娜
浏览 207回答 2
2回答

牧羊人nacy

您将所有属性作为普通值存储在实例的__dict__. 这意味着,如果没有任何进一步的提示,它们之间是无法区分的。Python 有两种机制来以特殊方式处理属性。如果您将在类本身中声明基类中的属性,并在__init__方法中初始化它们的值,则可以内省基类' __dict__(而不是实例的__dict__)或__annotations__同一类中的属性。但是,就像在示例中一样,一件简单的事情是使用特殊属性来记录添加到基类上的属性,然后将其作为属性的名称来源进行查询:class baseclass(object):    def __init__(self, **kwargs):        self.__dict__.update(kwargs)        self._numeric_attrs = set(kwargs.keys())    def calcValue(self):        return sum(getattr(self, attr) for attr in self._numeric_attrs)

慕容森

一个简单、安全和有效的——但增加了开销——将基类属性存储在一个不同的属性中并用于__getattr__为它们提供服务:class BaseClass(object):    def __init__(self, **kwargs):        self._attribs = kwargs    def __getattr__(self, name):        try:            return self._attribs[name]        except KeyError:            raise AttributeError("object {} has no attribute {}".format(type(self).__name__, name))    def calcValue(self):        return sum(self._attribs.values())我通常会尽量避免,__getattr__因为它会使代码更难检查和维护,但由于您的类已经没有明确的 API,因此在这里没有太大区别。
随时随地看视频慕课网APP

相关分类

Python
我要回答