3

假设您想要对象名称字符串末尾的对象:示例字符串是'first_class.second_class.third_class.id',字符串列表都采用 形式'X1object.X2object...XNobject.what_you_want_is_here_object'

在每种情况下,您都知道存在 X1object 的活动实例,无论其具体名称如何。对于示例字符串,代码已经调用了first_class. 您可以使用 加载first_classglobals['first_class']并且通常X1object使用 加载globals['X1object']

您想要的是字符串末尾的对象(通常是一个值)。因此,对于示例字符串,您需要id = first_class.second_class.third_class.id. 有没有一种简单的方法来转换字符串以获取其最终对象?

下面是我为处理这个问题而创建的代码,但这似乎是一种蛮力方法,依次获取每个属性,直到找到最后一个。

first_class = FirstClass()
first_class = go_do_something_wild_in_first_class(first_class)
...

attribute = 'first_class.second_class.third_class.id'
attribute_pieces = attribute.split('.')

fetch_attribute = lambda attribute, name: \
    attribute[name] if attribute == globals() else \
    getattr(attribute, name)

for name in attribute_pieces: # I changed the code from using an index to using a name
    if name == attribute_pieces[0]:
        attribute = fetch_attribute(globals(), name)
    else:
        attribute = fetch_attribute(attribute, name)

id = attribute
4

3 回答 3

4

您可以使用reduce()

def resolve_object(name):
    names = name.split('.')
    return reduce(getattr, names[1:], globals()[names[0]])

在这里,我们只是简单地查找names[0]为一个全局,然后遍历其余的名称,getattr为到目前为止的结果中的每个名称做一个。

演示:

>>> class Foo(object): pass
... 
>>> first_class = Foo()
>>> first_class.second_class = Foo()
>>> first_class.second_class.third_class = Foo
>>> first_class.second_class.third_class.id = 'baz'
>>> resolve_object('first_class.second_class.third_class.id')
'baz'
于 2013-03-05T16:36:27.083 回答
1

有一个名为 zope.dottedname 的 Python 库,它完全符合您的要求:

https://pypi.python.org/pypi/zope.dottedname

它将任意字符串解析为 Python 命名空间中的相应对象,包括对象的属性。

于 2013-03-05T16:29:39.420 回答
1

你应该使用importlib

attribute = 'first_class.second_class.third_class.id'
attribute_pieces = attribute.split('.')

id = getattr(importlib.import_module('.'.join(attribute_pieces[:-1]), attribute_pieces[-1])
于 2013-03-05T16:35:25.753 回答