[英]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.