繁体   English   中英

通过字符串查找解析全局命名空间中的Python对象

[英]Resolving a Python object in global namespace by string look up

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

在每种情况下,您都知道X1object有一个活动实例,无论其具体名称如何。 使用示例字符串,代码已经调用了first_class的实例。 您可以使用globals['first_class']加载first_class ,并通常使用globals['X1object']加载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

你可以使用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'

有一个名为zope.dottedname的Python库可以完全满足您的需求:

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

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

你应该使用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])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM