我有3个课程如下: -
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'
Run Code Online (Sandbox Code Playgroud)
现在我需要将bcvar作为字符串传递给某个函数,并获得类似于样本函数的var值,如下所示 -
`sample(a, 'b.c.var')` should return 'required result'`
Run Code Online (Sandbox Code Playgroud)
什么应该是pythonic方式来实现这一点这是我的尝试: -
for attr in ('b', 'c', 'var'):
a = getattr(a, attr)
>>> print a
required result
Run Code Online (Sandbox Code Playgroud)
您可以使用带有点名称表示法的operator.attrgetter,例如:
from operator import attrgetter
attrgetter('b.c.var')(a)
# 'required result'
Run Code Online (Sandbox Code Playgroud)
然后,如果您不喜欢该语法,请使用它来创建您的sample函数,例如:
def sample(obj, attribute):
getter = attrgetter(attribute)
return getter(obj)
Run Code Online (Sandbox Code Playgroud)
从上面链接的文档中,operator.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
Run Code Online (Sandbox Code Playgroud)
事实上 - 你的原始代码只是试图做相当于resolve_attr......