2015-10-22 3 views
0

Поиск в классах AddressBook использует регулярное выражение, чтобы найти строку, соответствующую шаблону, который является именем.Зачем мне нужно 2 метода __str__ для печати?

self.contacts петли через Contact класса и выводит из шаблона в словаре формате

import re 
import sys 


class Contact(object): 

    def __init__(self, match): 
     for key, value in match.groupdict().items(): 
      setattr(self, key, value) 

    def __str__(self): 
     return '\n'.join(
      sorted(
       ["\t{}: {}".format(key, val) for key, val in self.__dict__.items()])) 


class AddressBook(object): 

    def __init__(self, filename): 
     self.names_file = open(filename, encoding="utf-8") 
     self.data = self.names_file.read() 
     self.names_file.close() 
     line = re.compile('(?P<name>^([A-Z][a-z]*((\s)))+[A-Z][a-z]*$)') 
     self.contacts = [Contact(match) for match in line.finditer(self.data)] 

address_book = AddressBook('contacts.txt') 
print (address_book) 

Это даст мне питона объект:

<__main__.AddressBook object at 0x0338E410> 

Но если добавить еще один __str__ метод, как это ...

import re 
import sys 


class Contact(object): 
    ... #same code as above 


class AddressBook(object): 
    def __init__(self, filename): 
     self.names_file = open(filename, encoding="utf-8") 
     self.data = self.names_file.read() 
     self.names_file.close() 
     line = re.compile('(?P<name>^([A-Z][a-z]*((\s)))+[A-Z][a-z]*$)') 
     self.contacts = [Contact(match) for match in line.finditer(self.data)] 

    def __str__(self): 
     return '\n'.join('{}'.format(i) for i in self.contacts) 

address_book = AddressBook('contacts.txt') 
print (address_book) 

It ac tually печатает его:

name: Rick James 
name: Charlie Murphy 
name: Prince 

Мой вопрос, почему он дает мне объект питона, даже если у меня есть метод __str__ в Contact классе?

+5

Потому что вы печатаете «Адресную книгу», а не «Контакт»? –

+0

Есть ли другой способ сделать это, не прибегая к методам 2 '__str__'? – dyao

+1

@bLunt Вы можете выполнять всю работу в методе 'Адресная книга .__ str __()' и форматировать все экземпляры 'Contact', которые там содержатся, но, вероятно, лучше сохранить логику в двух методах' __str __() 'let каждый объект несет ответственность за свое собственное читаемое представление. – plamut

ответ

2

Причина заключается в том, что print() использует метод экземпляра __str__(), который по умолчанию использует метод __repr__() объекта. Теперь ваш второй пример переопределяет унаследованный метод __str__(), предоставляя вам хороший результат, который вы хотели.

Следующий пример иллюстрирует это поведение:

>>> class Foo: 
...  x = 42 
... 
>>> f = Foo() 
>>> print(f) 
<__main__.Foo object at 0x7fb12d4c6890> 
>>> class Foo2: 
...  x = 42 
...  def __str__(self): 
...   return 'x = {}'.format(self.x) 
... 
>>> f2 = Foo2() 
>>> print(f2) 
x = 42 

Для получения более подробной информации о различиях между __str__() и __repr__() вы также можете read this, очень хороший и исчерпывающее объяснение.

+0

Это хорошая ссылка, но лучший ответ может быть глубоко скрыт. :) –

+0

У вас есть точка здесь. :) Хотя ссылка имела в виду скорее «ресурс для дальнейшего чтения» _ для любознательного читателя, чем что-либо еще, я хотел избавить OP от потенциально ненужных деталей, просто описал основной механизм наблюдаемого поведения. :) – plamut

Смежные вопросы