簡體   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