我尝试从inst_baseA / inst_baseB
的实例访问Base
类的实例属性(ClassB
),具体取决于实例的属性({{1}对象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'
如果我将调用链接到getattr:
,我就克服了这个问题>>> 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(b, 'node'), b.x)
'base_A'
进行两次调用之外,有没有办法从孙子类中获取Base类的属性?
更新:我需要它的原因是我试图: - 从祖父母类(inst_baseA或inst_baseB)获取属性 - 取决于我的实例上的属性(x的值)
所以我的代码实际上是:getattr
。我第一次没有正确解释它,希望它现在更有意义。
答案 0 :(得分:2)
根据[Python]: getattr(object, name[, default]):
返回 object 的命名属性的值。 name 必须是字符串。如果字符串是对象属性之一的名称,则结果是该属性的值。例如,
getattr(x, 'foobar')
相当于x.foobar
。
node.inst_base
不属于b
,但是:
node
是b
inst_base
是b.node
因此,您需要为每个&#34;嵌套&#34;进行一次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'
或者,为了更进一步,您可以创建一个与&#34;嵌套&#34;一起使用的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>
但这可能非常低效(而且,也没有处理角落案件),你最好使用@Aran-Fey的建议。
答案 1 :(得分:2)
有operator.attrgetter
,但它真的不适合这种事情,所以语法很尴尬:
>>> operator.attrgetter('node.inst_base')(b)
'base'
但这确实非常不直观,所以为了避免让阅读代码的人感到困惑,最好还是推出自己的多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'