2013-03-05 54 views
3

假設您想要對象名稱字符串末尾的對象:示例字符串爲'first_class.second_class.third_class.id',並且字符串列表的形式均爲'X1object.X2object...XNobject.what_you_want_is_here_object'通過字符串查找解析全局名稱空間中的Python對象

在任何情況下,您都知道有一個活動的X1object實例,無論其具體名稱如何。使用示例字符串,代碼已經調用first_class的實例。您可以使用globals['first_class']加載first_class,並一般加載X1objectglobals['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 
+0

你想要類X的實際情況?實際的目標是什麼?因爲可能有更簡單的解決方案。 – ninMonkey 2013-03-05 16:25:41

+0

我有一個像'first_class.second_class.third_class.id''這樣的字符串列表。我想迭代列表並返回最後一個對象,就好像我在寫'id = first_class.second_class.third_class.id'。輸入是一個字符串,輸出是將被調用的實際對象。 – Cole 2013-03-05 16:31:29

回答

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' 
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])