Python 如何访问对象';如果对象是其他对象的属性,则使用与名称对应的字符串创建属性

Python 如何访问对象';如果对象是其他对象的属性,则使用与名称对应的字符串创建属性,python,Python,我有以下三个班:- class C(object): def __init__(self, v): self.var = v class B(object): def __init__(self, c): self.c = c class A(object): def __init__(self, b): self.b = b I have created instances as c = C("required r

我有以下三个班:-

class C(object):
    def __init__(self, v):
        self.var = v

class B(object):
    def __init__(self, c):
        self.c = c

class A(object):
    def __init__(self, b):
        self.b = b

I have created instances as 
c = C("required result")
b = B(c)
a = A(b)

>>> a.b.c.var
'required result'
现在我需要将b.c.var作为字符串传递给某个函数,并获得类似于示例函数的var值,如下所示-

`sample(a, 'b.c.var')` should return 'required result'`
要实现这一点,pythonic的方法应该是什么 这是我的尝试:

for attr in ('b', 'c', 'var'):
    a = getattr(a, attr)
>>> print a
required result

我想这是更准确的方法。(使用
尝试,但不包括
构造):


我想这是更准确的方法。(使用
尝试,但不包括
构造):

您可以使用带点名称符号的,例如:

from operator import attrgetter
attrgetter('b.c.var')(a)
# 'required result'
然后,如果您不喜欢该语法,请使用它来生成
sample
函数,例如:

def sample(obj, attribute):
    getter = attrgetter(attribute)
    return getter(obj)
从上面链接的文档中,
操作符.attrgetter
使用与以下代码等效的代码:

def attrgetter(*items):
    if any(not isinstance(item, str) for item in items):
        raise TypeError('attribute name must be a string')
    if len(items) == 1:
        attr = items[0]
        def g(obj):
            return resolve_attr(obj, attr)
    else:
        def g(obj):
            return tuple(resolve_attr(obj, attr) for attr in items)
    return g

def resolve_attr(obj, attr):
    for name in attr.split("."):
        obj = getattr(obj, name)
    return obj
因此,事实上-您的原始代码只是尝试执行与您可以使用的采用虚线名称表示法的
解析\u attr
..

等效的操作,例如:

from operator import attrgetter
attrgetter('b.c.var')(a)
# 'required result'
然后,如果您不喜欢该语法,请使用它来生成
sample
函数,例如:

def sample(obj, attribute):
    getter = attrgetter(attribute)
    return getter(obj)
从上面链接的文档中,
操作符.attrgetter
使用与以下代码等效的代码:

def attrgetter(*items):
    if any(not isinstance(item, str) for item in items):
        raise TypeError('attribute name must be a string')
    if len(items) == 1:
        attr = items[0]
        def g(obj):
            return resolve_attr(obj, attr)
    else:
        def g(obj):
            return tuple(resolve_attr(obj, attr) for attr in items)
    return g

def resolve_attr(obj, attr):
    for name in attr.split("."):
        obj = getattr(obj, name)
    return obj

因此,事实上-您的原始代码只是尝试执行与解决\u attr

问题等效的操作,您能更具体地说明您的问题吗?拥有更具可读性的代码将是拥有更具Python风格的代码的第一步。看看getattr()和str.split()@WilliamFernandes我的尝试有一个更新问题,你尝试的结果是什么?你几乎完成了,不是吗?您只需要使用.split('.')将“b.c.var”转换为('b','c','var'),除非我遗漏了一些内容。您能更具体地说明您的问题吗?拥有更具可读性的代码将是拥有更具Python风格的代码的第一步。看看getattr()和str.split()@WilliamFernandes我的尝试有一个更新问题,你尝试的结果是什么?你几乎完成了,不是吗?您只需要使用.split('.')将'b.c.var'转换为('b','c','var'),除非我遗漏了什么