什么是__str__和__repr__的目的是什么?

问题描述 投票:69回答:6

我真的不明白的地方是__str__和Python中__repr__。我的意思是,我得到__str__返回一个对象的字符串表示。但是,为什么我需要吗?在什么用例场景?另外,我读到__repr__的用法

但我不明白的是,在这里我会使用它们?

python
6个回答
76
投票

__repr__

repr()内置函数和字符串转换调用(反引号)来计算对象的“正式”字符串表示。如果可能的话,这应该是一个可以用来重建具有相同的值(给定一个适当的环境)的对象的有效的Python表达式。

__str__

str()内置函数和print语句调用来计算对象的“非正式”的字符串表示。

使用__str__如果你有一个类,你会希望有一个信息/非正式输出,当你使用这个对象作为字符串的一部分。例如。您可以定义Django模型,然后把它在Django的管理界面中呈现__str__方法。而不是像<Model object>你会得到喜欢一个人的姓氏和名字,这个名字和事件的日期等。


__repr____str__是相似的,实际上有时能同(实施例从BaseSet类在sets.py从标准库):

def __repr__(self):
    """Return string representation of a set.

    This looks like 'Set([<list of elements>])'.
    """
    return self._repr()

# __str__ is the same as __repr__
__str__ = __repr__

53
投票

在您使用它的人都发生了很多是在交互式会话。如果你打印一个对象,然后它的__str__方法将被调用,而如果你只是使用对象本身则显示出其__repr__

>>> from decimal import Decimal
>>> a = Decimal(1.25)
>>> print(a)
1.25                  <---- this is from __str__
>>> a
Decimal('1.25')       <---- this is from __repr__

__str__旨在为人类可读的可能,而__repr__的目标应该是东西,可以用来重新创建对象,尽管它往往不会像当初究竟是如何创建的,因为在这种情况下。

这也是不寻常的两个__str____repr__返回相同的值(当然,对于内置类型)。


14
投票

蝈蝈,有疑问时go to the mountainread the Ancient Texts。在他们身上你会发现,__repr __()应该:

如果可能的话,这应该是一个可以用来重新创建具有相同的值对象的有效的Python表达式。


11
投票

建立和以前的答案,并呈现出一些更多的例子。如果使用得当,strrepr之间的差别是显而易见的。总之repr应当返回一个可复制粘贴到重建对象的确切状态的字符串,而strloggingobserving调试结果是有用的。下面是一些例子,以查看一些已知的文库中不同的输出。

Datetime

print repr(datetime.now())    #datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)
print str(datetime.now())     #2017-12-12 18:49:27.134452

str好打印到日志文件,其中为repr可以,如果你想直接运行或转储它作为命令到一个文件中重新利用。

x = datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)

Numpy

print repr(np.array([1,2,3,4,5])) #array([1, 2, 3, 4, 5])
print str(np.array([1,2,3,4,5]))  #[1 2 3 4 5]

在与NumPy的repr又是直接消耗的。

Custom Vector3 example

class Vector3(object):
    def __init__(self, args):
        self.x = args[0]
        self.y = args[1]
        self.z = args[2]

    def __str__(self):
        return "x: {0}, y: {1}, z: {2}".format(self.x, self.y, self.z)

    def __repr__(self):
        return "Vector3([{0},{1},{2}])".format(self.x, self.y, self.z)

在该示例中,再次repr返回可直接饮用/执行的字符串,而str是作为调试输出更加有用。

v = Vector3([1,2,3])
print str(v)     #x: 1, y: 2, z: 3
print repr(v)    #Vector3([1,2,3])

有一点要记住,如果没有定义strreprstr会自动调用repr。所以,这是一件好事,至少定义repr


1
投票

str将是非正式的,可读的格式,而repr会给官方对象表示。

class Complex:
    # Constructor
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag

    # "official" string representation of an object
    def __repr__(self):
        return 'Rational(%s, %s)' % (self.real, self.imag)

    # "informal" string representation of an object (readable)
    def __str__(self):
        return '%s + i%s' % (self.real, self.imag)

    t = Complex(10, 20)

    print (t)     # this is usual way we print the object
    print (str(t))  # this is str representation of object 
    print (repr(t))  # this is repr representation of object   

Answers : 

Rational(10, 20) # usual representation
10 + i20      # str representation
Rational(10, 20)  # repr representation

1
投票

让我们有一个类没有__str__功能。

class Employee:

    def __init__(self, first, last, pay):
        self.first = first 
        self.last = last
        self.pay = pay

emp1 = Employee('Ivan', 'Smith', 90000)

print(emp1)

当我们打印类,emp1的这种情况下,这就是我们得到:

<__main__.Employee object at 0x7ff6fc0a0e48>

这是不是非常有帮助,当然这不是我们想要打印的内容,如果我们都用它来显示(像HTML)

所以,现在,同一类,但__str__功能:

class Employee:

    def __init__(self, first, last, pay):
        self.first = first 
        self.last = last
        self.pay = pay

    def __str__(self):
        return(f"The employee {self.first} {self.last} earns {self.pay}.")
        # you can edit this and use any attributes of the class

emp2 = Employee('John', 'Williams', 90000)

print(emp2)

现在,而不是打印,有一个对象,我们得到了我们与__str__函数返回指定:

The employee John Williams earns 90000

© www.soinside.com 2019 - 2024. All rights reserved.