使用g获取祖父母类的属性

2024-06-13 06:06:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试从ClassB的实例访问Base类的实例属性(inst_baseA / inst_baseB),具体取决于对象ClassB的实例属性(self.x)。你知道吗

这是我的密码:

class Base(object):
    def __init__(self):
        self.inst_baseA = 'base_B'
        self.inst_baseB = 'base_A'


class ClassA(object):
    def __init__(self):
        self.node = Base()


class ClassB(ClassA):
    def __init__(self):
        super(ClassB, self).__init__()
        self.x = 'base_A'

这是我首先尝试的:

>>> b = ClassB()
>>> getattr(b, 'node.inst_{}'.format(b.x))

Traceback (most recent call last):
  File "<pyshell#26>", line 1, in <module>
    getattr(b, 'node.inst_{}'.format(b.x))
AttributeError: 'ClassB' object has no attribute 'node.inst_base_A'

如果我链接对getattr的调用,我就克服了这个问题:

>>> getattr(getattr(b, 'node'), b.x)
'base_A'

出于好奇:除了对getattr进行两次调用之外,还有没有其他方法可以从孙子类中获取基类的属性?你知道吗


更新:我之所以需要它是因为我想: -获取祖父母类(inst\u baseA或inst\u baseB)的属性 -取决于实例上的属性(x的值)

所以我的代码实际上是这样的:getattr(self, 'node.{}'.format(self.x))。我第一次解释的不对,希望现在能讲得通。你知道吗


Tags: 实例selfnodebase属性objectinitdef
2条回答

根据[Python]: getattr(object, name[, default])

Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar.

node.inst_base不是b的属性,而是:

  • nodeb的属性
  • inst_baseb.node的属性

因此,每个“嵌套”级别需要一个getattr调用。你知道吗

考虑到我已将您的代码粘贴到解释器的交互窗口中:

>>> getattr(b, 'node.inst_base')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'ClassB' object has no attribute 'node.inst_base'
>>>
>>> getattr(getattr(b, "node", None), "inst_base", None)
'base'

或者,为了更进一步,您可以创建一个使用“嵌套”属性名的getter:

>>> def getattr_nested(obj, nested_attr):
...     attrs = nested_attr.split(".")
...     ret = obj
...     for attr in attrs:
...             ret = getattr(ret, attr, None)
...             if ret is None:
...                     return None
...     return ret
...
>>>
>>> getattr_nested(b, "node.inst_base")
'base'
>>> getattr_nested(b, "node.inst_base2")
>>> getattr_nested(b, "node")
<__main__.Base object at 0x0000021A2A593D30>

但这可能是非常低效的(而且,也不能处理极端情况),你最好使用@aranfey的建议。你知道吗

^{},但它实际上并不适用于这种类型的东西,因此语法非常笨拙:

>>> operator.attrgetter('node.inst_base')(b)
'base'

但这确实非常不直观,因此为了避免让阅读您代码的人感到困惑,最好使用自己的multi-getattr:

def get_multi_attr(obj, attrs):
    for attr in attrs.split('.'):
        obj = getattr(obj, attr)
    return obj
>>> get_multi_attr(b, 'node.inst_base')
'base'

相关问题 更多 >