2011-08-25 37 views
6

這是一個相當直接的問題,希望你們都能啓發我。在下面的例子中,我如何定義__repr__被動態設置爲self.name?在python中動態創建類和__repr__

謝謝大家!

import re 

inputlist = 'Project="Sparcy" Desc=""\nProject="Libs" Desc=""\nProject="Darwin" Desc=""\nProject="Aaple" Desc="The big project"' 

regex = re.compile('([^ =]+) *= *("[^"]*"|[^ ]*)') 

results = [] 
for project in inputlist.split("\n"): 
    items = [ (k.strip(), v.strip()) for k, v in regex.findall(project)] 
    if len(items) < 2: 
     print("Houston we have a problem - Only %s k/v pair found for %s" % (len(items), project)) 
     continue 
    item_dict = dict(items[1:]) 
    item_dict['name'] = items[0][1] 
    klass = type(items[0][0], (object,), item_dict) 
    results.append(klass) 

print results 

我所尋找的是這個

僞代碼

for result in results 
type(result) → Project 
print result → Sparky 

回答

3

我猜你想

print results 

返回

["Sparcy", "Libs", "Darwin", "Aaple"] 
  1. 打印列表顯示其元素的repr。
  2. repr(elt)type(elt).__repr__決定。
  3. 由於在這種情況下元素是類,因此您需要爲該類的類型設置 __repr__

import re 

inputlist = '''\ 
Project="Sparcy" Desc="" 
Project="Libs" Desc="" 
Project="Darwin" Desc="" 
Project="Aaple" Desc="The big project" 
Site="Phoenix" Protocol="Cheese"''' 

regex = re.compile('([^ =]+) *= *("[^"]*"|[^ ]*)') 

results = [] 
for project in inputlist.split("\n"): 
    items = [ (k.strip(), v.strip()) for k, v in regex.findall(project)] 
    if len(items) < 2: 
     print("Houston we have a problem - Only %s k/v pair found for %s" % (len(items), project)) 
     continue 
    item_dict = dict(items[1:]) 
    item_dict['name'] = items[0][1] 
    projectname=items[0][0] 
    metametaklass=type('meta_'+projectname,(type,),{'__repr__':lambda cls: cls.__name__}) 
    metaklass=metametaklass(projectname,(type,),{'__repr__':lambda cls: cls.name}) 
    klass=metaklass(projectname+'_class', (object,), item_dict) 
    results.append(klass) 

print(results) 

產生

["Sparcy", "Libs", "Darwin", "Aaple", "Phoenix"] 

for result in results: 
    print(type(result)) 
    print(result)  
    print('-'*80) 

產量

Project 
"Sparcy" 
-------------------------------------------------------------------------------- 
Project 
"Libs" 
-------------------------------------------------------------------------------- 
Project 
"Darwin" 
-------------------------------------------------------------------------------- 
Project 
"Aaple" 
-------------------------------------------------------------------------------- 
Site 
"Phoenix" 
-------------------------------------------------------------------------------- 

PS。請注意,這是__repr__的變形,因爲對象的repr應該是對象的明確字符串表示形式。也就是說,它應該提供足夠的信息來重現對象。你可能應該定義一個不同的print函數,而不是與元類混淆。

+0

你知道如何定義類型嗎?我理解這個作品的方式是,如果定義了__metaclass__,它將使用它。你正在利用'__repr__'的優勢。我怎麼不傳播'__metaclass__'。 __goal→類型(Sparky)== Project__ – rh0dium

+0

@ rh0dium:我不確定我是否理解這個問題。我編輯我的帖子,所以'print(type(klass))'會打印'Project'。 – unutbu

+0

但它不再是動態的。當你這樣做時會發生什麼..''inputlist ='Site =「Phoenix」Protocol =「Cheese」\ n' – rh0dium