2011-08-25 27 views
6

Đây là một câu hỏi khá đơn giản hy vọng tất cả các bạn có thể khai sáng cho tôi. Trong ví dụ bên dưới, làm cách nào để xác định __repr__ được tự động đặt thành self.name?Tạo động các lớp trong python và __repr__

Cảm ơn tất cả!

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 

Những gì tôi đang tìm kiếm là này

mã giả

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

Trả lời

3

Tôi đoán rằng bạn muốn

print results 

trở

["Sparcy", "Libs", "Darwin", "Aaple"] 
  1. In danh sách hiển thị thông tin về các phần tử của nó.
  2. repr(elt) được xác định bởi type(elt).__repr__.
  3. Vì trong trường hợp này các yếu tố là các lớp, bạn cần phải đặt __repr__ cho loại lớp học.

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) 

mang

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

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

sản lượng

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

PS. Lưu ý rằng đây là sự đảo lộn của __repr__, vì repr của một đối tượng được cho là một biểu diễn chuỗi rõ ràng của đối tượng. Nghĩa là, nó được cho là cung cấp đủ thông tin để tái tạo đối tượng. Có thể bạn nên định nghĩa một hàm print khác thay vì làm rối tung bằng metaclasses.

+0

Bạn có biết cách xác định loại không. Cách tôi hiểu công trình này là nếu '__metaclass__' được định nghĩa thì nó sẽ sử dụng nó. Bạn đang tận dụng điều đó cho '__repr__'. Làm thế nào để tôi không tuyên truyền cho '__metaclass__'. Các __goal → loại (Sparky) == Project__ – rh0dium

+0

@ rh0dium: Tôi không chắc tôi hiểu câu hỏi. Tôi đã chỉnh sửa bài đăng của mình để 'print (type (klass))' sẽ in 'Project'. – unutbu

+0

Nhưng sau đó nó không còn năng động nữa. Điều gì sẽ xảy ra khi bạn gieo nó .. 'inputlist = 'Site =" Phoenix "Protocol =" Cheese "\ n' – rh0dium

Các vấn đề liên quan