__repr__, __str__ 缺乏理解

__repr__, __str__ lack of understanding

我现在正在研究Python类和运行这本书没有太多解释的东西。

我有一个代码:

class Human(object):
    def __init__(self,*args,**kwargs):
        self.first_name = kwargs.setdefault('first')
        self.last_name = kwargs.setdefault('last')
        self.height = kwargs.setdefault('height')
        self.weight = kwargs.setdefault('weight')

def bmi(self):
    return self.weight/float(self.height)**2
Human.bmi = bmi

def human_str(self):
    return '{} {}'.format(self.first_name, self.last_name)
Human.__str__ = human_str

me = Human(first='Seth', last='Gibson')   
adam_mechtley = Human(first='Adam', last='Mechtley', weight = 78, height = 1.85) 
sis = Human(first='Ruth',last='Gibson')
babysis = Human(first='Emily',last='Gibson')
print(sis)
#Prints : proper name
print(sis,babysis)
#Prints : <place in memory>

我总体上理解发生了什么,但是 问题是,为什么当我只打印一个实例时,str() 属性有效,但如果我尝试同时打印两个实例,repr() 属性正在被使用?

感谢您的宝贵时间!

原因是在Python2中,print(a,b)不打印ab,而是打印(a, b),即一个tuple。因此,print(a) 将调用 str(a)(...) 不会将单个元素变成元组),而 print(a,b) 调用元组的 __str__ (a, b),这又会调用各个元素的 __repr__。 (如果没有定义__repr__,则默认打印类型和内存地址。)

最小示例:

class Test:
    def __str__(self):
        return "str"
    def __repr__(self):
        return "repr"

t = Test()
print(t)
print(t, t)

输出使用Python 2:

str
(repr, repr)

在 Python 3 上,或者在 Python 2 中执行 print t, t 时,如果没有 (...)print 将调用 str 直接在两个元素上。

str
str str

此外,与问题无关,我建议将您的 Human class 更改为这样的内容,定义正确的方法而不使用 kwargs.

class Human(object):
    def __init__(self, first, last, height=None, weight=None):
        self.first_name = first
        self.last_name = last
        self.height = height
        self.weight = weight

    def bmi(self):
        return self.weight/float(self.height)**2

    def __str__(self):
        return '{} {}'.format(self.first_name, self.last_name)

这里有一个更正常的方式来定义你之前写的class

class Human(object): 
    def __init__(self,*args,**kwargs):
        self.first_name = kwargs.setdefault('first')
        self.last_name = kwargs.setdefault('last')
        self.height = kwargs.setdefault('height')
        self.weight = kwargs.setdefault('weight') 
    def bmi(self):
        return self.weight/float(self.height)**2
    def __str__(self):
        return '{0} {1}'.format(self.first_name, self.last_name)

你剩下的问题可能在这里得到了回答: Difference between __str__ and __repr__?