为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

红颜莎娜 2021-10-26 18:52:42
我有一个包含数字属性的基类,这些属性在初始化时作为字典简单地传递给它,然后添加到实例的字典中: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 = 6instance.calcValue()但是因为 vars(self) 将返回完整的字典,不包括来自 childclass 属性的字符串,当然不能添加。有没有办法只访问属于各自派生类的实例的属性?
查看完整描述

2 回答

?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

您将所有属性作为普通值存储在实例的__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)


查看完整回答
反对 回复 2021-10-26
?
慕容森

TA贡献1853条经验 获得超18个赞

一个简单、安全和有效的——但增加了开销——将基类属性存储在一个不同的属性中并用于__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,因此在这里没有太大区别。


查看完整回答
反对 回复 2021-10-26
  • 2 回答
  • 0 关注
  • 206 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信