2011-08-25 22 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" 
-------------------------------------------------------------------------------- 
を生み出します0

PS。これはオブジェクトのreprがオブジェクトの明白な文字列表現であると考えられるので、これは__repr__の倒錯であることに注意してください。つまり、オブジェクトを再現するのに十分な情報を提供することになっています。おそらく、別のprint関数を定義する必要があります。

+0

タイプを定義する方法を知っていますか。私がこの作業を理解する方法は、 '__metaclass__'が定義されている場合にそれを使用することです。あなたは '__repr__'のためにそれを利用しています。 '__metaclass__'のためにどのように伝播しないのですか? __goal→type(Sparky)== Project__ – rh0dium

+0

@ rh0dium:私は質問を理解しているかどうかはわかりません。私は自分の投稿を編集して 'print(type(klass))'が 'Project'を印刷するようにしました。 – unutbu

+0

しかしそれはもはや動的です。 'inputlist = 'Site =" Phoenix "Protocol =" Cheese "\ n" – rh0dium

関連する問題