为什么我需要2 __str__方法来打印?

时间:2015-10-22 03:27:17

标签: python oop

AddressBook类查找使用正则表达式来查找与模式匹配的字符串,这是一个名称。

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)

这会给我一个python对象:

<__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)

它实际打印出来:

name: Rick James
name: Charlie Murphy
name: Prince

我的问题是,为什么它给了我一个python对象,即使我在__str__类中有一个Contact方法?

1 个答案:

答案 0 :(得分: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,这是一个非常好的详尽解释。