2012-06-11 7 views
0

У меня есть класс контейнера, который я хотел бы использовать для печати всех элементов в нем.Правильное использование __repr __() в python?

Я хотел бы напечатать их в файл или консоль.

Я выложил элемент (Patch) и контейнерный класс, как показано ниже, и __repr__(self).
Я не уверен, что понял цель __repr__(), и мне интересно, что здесь все в порядке.

class Patch: 
    def __init__(self, folder_name, file_name): 
     self.folder_name = folder_name 
     self.file_name = file_name 
     self.full_path = os.path.join(self.folder_name, self.file_name) 
     self.file_hash = md5_for_file(open(self.full_path, 'r')) 
     self.file_size = os.path.getsize(self.full_path) 

    def __repr__(self): 
     return "%s %s %s" % (self.file_name, self.file_hash, self.file_size) 

class PatchContainer: 
    def __init__(self): 
     self.patch_folder_dict = collections.OrderedDict() 
     self.patch_file_set = set() 
    def addPatch(self, patch): 
     if patch.file_name in self.patch_file_set: 
      print '*** Delete the file ', patch.full_path, ' ***' 
      return 
     self.patch_file_set.add(patch.file_name) 
     if not patch.folder_name in self.patch_folder_dict: 
      self.patch_folder_dict[patch.folder_name] = [patch] 
     else: 
      self.patch_folder_dict[patch.folder_name].append(patch) 

    def prettyPrint(self, writeable_object=PATCH_META_FILE): 
     sys.stdout = writeable_object 
     for patch_folder in self.patch_folder_dict.keys(): 
      print patch_folder 
      patch_list = self.patch_folder_dict[patch_folder] 
      for patch in patch_list: 
       print patch 
     sys.stdout = sys.__stdout__ 

Он работает по назначению, но, пожалуйста, прокомментируйте, хорошо ли стиль/использование.

ответ

4

Похоже, вы, вероятно, хотите __str__. Они похожи, но __str__ возвращает что-то, предназначенное для потребления человеком; __repr__ должен возвращать что-то, предназначенное для потребления Python - это должно быть либо выражение Python, которое будет оцениваться равным объектом, либо что-то в угловых скобках, как по умолчанию <classname object at id>. Смотрите documentation для встроено repr(object), который заканчивается вызовом object.__repr__():

Для многих типов, эта функция делает попытку вернуть строку, уступит объект с тем же значением, когда передается Eval(), иначе представление строка в угловых скобках , который содержит имя типа объекта вместе с дополнительной информацией

+5

Raymond Hettinger (@raymondh) написал на эту тему на днях: «Когда возможно, методы __repr__' должны показать, как был создан объект. Инвариант должен быть:' eval (repr (obj)) == obj'. " –

+0

как насчет prettyPrint() функция? Я мог бы определить __str() __ __str() __ вместо Python. – eugene

+0

@ Юджин да. Вероятно, было бы разумнее сделать это таким образом, и поэтому вместо вызова 'patchcontainer.prettyprint (file)' вы бы сделали 'print >> файл patchcontainer' (или' print (patchcontainer, file = file) ', если вы это сделаете 'from __future__ import print_function'). Почти всегда хорошая идея отделить классы бизнес-уровня от кода, который делает IO. – lvc

2

это люди-читаемым представление объекта.

  • "Цель языка Python __repr__": clicky
  • "Разница между __str__ и __repr__ в Python": clicky
  • Python документация: clicky
Смежные вопросы