问题:__str__和__repr__之间的区别?

__str____repr__Python 和有什么不一样?

What is the difference between __str__ and __repr__ in Python?


回答 0

亚历克斯总结得很好,但令人惊讶的是,它太简洁了。

首先,让我重申亚历克斯(Alex)帖子中的要点:

  • 默认的实现是无用的(很难想到不会的,但是是的)
  • __repr__ 目标是明确
  • __str__ 目标是可读
  • 容器__str__使用的包含对象__repr__

默认实现是没有用的

这主要是令人惊讶的,因为Python的默认设置往往非常有用。但是,在这种情况下,具有默认值的__repr__行为如下:

return "%s(%r)" % (self.__class__, self.__dict__)

太危险了(例如,如果对象之间互相引用,则很容易陷入无限递归)。因此,Python应对了。请注意,有一个默认值为true:如果__repr__已定义,但未定义,__str__则该对象的行为就好像__str__=__repr__

简单来说,这意味着:您实现的几乎每个对象都应具有__repr__可用于理解该对象的功能。实施__str__是可选的:如果您需要“漂亮的打印”功能(例如,由报告生成器使用),请执行此操作。

的目标__repr__是明确的

我马上说出来-我不相信调试器。我真的不知道如何使用任何调试器,也从未认真使用过。此外,我相信调试器的最大缺陷是它们的基本特性–我调试的大多数故障是很久以前发生的,它位于一个遥远的星系中。这意味着我确实以宗教的热情相信伐木。日志记录是任何体面的“一劳永逸”服务器系统的命脉。使用Python可以轻松记录日志:也许有一些特定于项目的包装器,您只需要一个

log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)

但是,您必须做最后一步-确保实现的每个对象都有一个有用的代表,这样的代码才能正常工作。这就是为什么出现“评估”问题的原因:如果您有足够的信息eval(repr(c))==c,这意味着您知道所有要了解的信息c。如果那很容易(至少以一种模糊的方式),那就去做。如果没有,请确保您有足够的信息c。我通常使用类似eval的格式:"MyClass(this=%r,that=%r)" % (self.this,self.that)。这并不意味着您可以实际构造MyClass,也不意味着它们是正确的构造方法参数—但这是表达“这是您需要了解的有关该实例的一切”的有用形式。

注意:我在%r上面使用过,不是%s。您总是想在实现中使用repr()[或%r等效地格式化字符] __repr__,否则您就无法实现repr的目标。你要能够区分MyClass(3)MyClass("3")

的目标__str__是可读

具体来说,它并非旨在明确-请注意str(3)==str("3")。同样,如果实现IP抽象,则让其str看起来像192.168.1.1很好。在实现日期/时间抽象时,str可以是“ 2010/4/12 15:35:22”,等等。目标是以用户(而不是程序员)想要阅读的方式表示它。砍掉无用的数字,冒充其他类别-只要它支持可读性,它就是一种进步。

容器__str__使用的包含对象__repr__

这似乎令人惊讶,不是吗?它有点,但是如果使用它们,它们的可读性如何__str__

[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]

不是特别的。具体而言,容器中的字符串会发现太容易打乱其字符串表示形式。记住,面对歧义,Python抵制了猜测的诱惑。如果您在打印列表时需要上述行为,则只需

print "[" + ", ".join(l) + "]"

(您可能还可以弄清楚如何处理字典。

摘要

实现__repr__你实现任何类。这应该是第二天性。__str__如果您认为有一个字符串版本会影响可读性会很有用,请实施。

Alex summarized well but, surprisingly, was too succinct.

First, let me reiterate the main points in Alex’s post:

  • The default implementation is useless (it’s hard to think of one which wouldn’t be, but yeah)
  • __repr__ goal is to be unambiguous
  • __str__ goal is to be readable
  • Container’s __str__ uses contained objects’ __repr__

Default implementation is useless

This is mostly a surprise because Python’s defaults tend to be fairly useful. However, in this case, having a default for __repr__ which would act like:

return "%s(%r)" % (self.__class__, self.__dict__)

would have been too dangerous (for example, too easy to get into infinite recursion if objects reference each other). So Python cops out. Note that there is one default which is true: if __repr__ is defined, and __str__ is not, the object will behave as though __str__=__repr__.

This means, in simple terms: almost every object you implement should have a functional __repr__ that’s usable for understanding the object. Implementing __str__ is optional: do that if you need a “pretty print” functionality (for example, used by a report generator).

The goal of __repr__ is to be unambiguous

Let me come right out and say it — I do not believe in debuggers. I don’t really know how to use any debugger, and have never used one seriously. Furthermore, I believe that the big fault in debuggers is their basic nature — most failures I debug happened a long long time ago, in a galaxy far far away. This means that I do believe, with religious fervor, in logging. Logging is the lifeblood of any decent fire-and-forget server system. Python makes it easy to log: with maybe some project specific wrappers, all you need is a

log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)

But you have to do the last step — make sure every object you implement has a useful repr, so code like that can just work. This is why the “eval” thing comes up: if you have enough information so eval(repr(c))==c, that means you know everything there is to know about c. If that’s easy enough, at least in a fuzzy way, do it. If not, make sure you have enough information about c anyway. I usually use an eval-like format: "MyClass(this=%r,that=%r)" % (self.this,self.that). It does not mean that you can actually construct MyClass, or that those are the right constructor arguments — but it is a useful form to express “this is everything you need to know about this instance”.

Note: I used %r above, not %s. You always want to use repr() [or %r formatting character, equivalently] inside __repr__ implementation, or you’re defeating the goal of repr. You want to be able to differentiate MyClass(3) and MyClass("3").

The goal of __str__ is to be readable

Specifically, it is not intended to be unambiguous — notice that str(3)==str("3"). Likewise, if you implement an IP abstraction, having the str of it look like 192.168.1.1 is just fine. When implementing a date/time abstraction, the str can be “2010/4/12 15:35:22”, etc. The goal is to represent it in a way that a user, not a programmer, would want to read it. Chop off useless digits, pretend to be some other class — as long is it supports readability, it is an improvement.

Container’s __str__ uses contained objects’ __repr__

This seems surprising, doesn’t it? It is a little, but how readable would it be if it used their __str__?

[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]

Not very. Specifically, the strings in a container would find it way too easy to disturb its string representation. In the face of ambiguity, remember, Python resists the temptation to guess. If you want the above behavior when you’re printing a list, just

print "[" + ", ".join(l) + "]"

(you can probably also figure out what to do about dictionaries.

Summary

Implement __repr__ for any class you implement. This should be second nature. Implement __str__ if you think it would be useful to have a string version which errs on the side of readability.


回答 1

我的经验法则: __repr__针对开发人员,__str__针对客户。

My rule of thumb: __repr__ is for developers, __str__ is for customers.


回答 2

除非您特别采取行动以确保其他情况,否则大多数类在以下两个方面均不会产生有用的结果:

>>> class Sic(object): pass
... 
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>> 

如您所见-没有区别,没有信息超出类和对象的id。如果仅覆盖两个…之一:

>>> class Sic(object): 
...   def __repr__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
foo
>>> class Sic(object):
...   def __str__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
<__main__.Sic object at 0x2617f0>
>>> 

如您所见,如果您覆盖__repr__,这也用于__str__,但反之则不。

要知道的其他关键要点:__str__在内置容器上__repr__,对包含的项目使用,而不是对__str__。而且,尽管在典型文档中找到了有关主题的字眼,但几乎没有人为使__repr__对象的字符串成为eval可用于构建相等对象的字符串而烦恼(这太难了,而且不知道相关模块的实际导入方式会使它实际上完全不可能)。

因此,我的建议是:着重于使__str__合理的人类可读性,并__repr__尽可能地做到模棱两可,即使这会干扰使__repr__的返回值可以接受为__eval__!的模糊不可实现的目标。

Unless you specifically act to ensure otherwise, most classes don’t have helpful results for either:

>>> class Sic(object): pass
... 
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>> 

As you see — no difference, and no info beyond the class and object’s id. If you only override one of the two…:

>>> class Sic(object): 
...   def __repr__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
foo
>>> class Sic(object):
...   def __str__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
<__main__.Sic object at 0x2617f0>
>>> 

as you see, if you override __repr__, that’s ALSO used for __str__, but not vice versa.

Other crucial tidbits to know: __str__ on a built-on container uses the __repr__, NOT the __str__, for the items it contains. And, despite the words on the subject found in typical docs, hardly anybody bothers making the __repr__ of objects be a string that eval may use to build an equal object (it’s just too hard, AND not knowing how the relevant module was actually imported makes it actually flat out impossible).

So, my advice: focus on making __str__ reasonably human-readable, and __repr__ as unambiguous as you possibly can, even if that interferes with the fuzzy unattainable goal of making __repr__‘s returned value acceptable as input to __eval__!


回答 3

__repr__:python对象的表示形式,通常eval会将其转换回该对象

__str__:是您认为的文本形式的对象

例如

>>> s="""w'o"w"""
>>> repr(s)
'\'w\\\'o"w\''
>>> str(s)
'w\'o"w'
>>> eval(str(s))==s
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    w'o"w
       ^
SyntaxError: EOL while scanning single-quoted string
>>> eval(repr(s))==s
True

__repr__: representation of python object usually eval will convert it back to that object

__str__: is whatever you think is that object in text form

e.g.

>>> s="""w'o"w"""
>>> repr(s)
'\'w\\\'o"w\''
>>> str(s)
'w\'o"w'
>>> eval(str(s))==s
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    w'o"w
       ^
SyntaxError: EOL while scanning single-quoted string
>>> eval(repr(s))==s
True

回答 4

简而言之,的目标__repr__是明确且__str__可读。

这是一个很好的例子:

>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2012-03-14 09:21:58.130922'
>>> repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'

阅读此文档以获取代表:

repr(object)

返回包含对象的可打印表示形式的字符串。这与转化产生的值相同(反引号)。能够以常规功能访问此操作有时很有用。对于许多类型,此函数会尝试返回一个字符串,该字符串将在传递给时产生一个具有相同值的对象eval(),否则表示形式是一个用尖括号括起来的字符串,其中包含对象类型的名称以及其他信息通常包括对象的名称和地址。类可以通过定义__repr__()方法来控制此函数为其实例返回的内容。

这是str的文档:

str(object='')

返回一个字符串,其中包含对象的可很好打印的表示形式。对于字符串,这将返回字符串本身。与的区别repr(object)在于,str(object)并非总是尝试返回可接受的字符串eval();它的目标是返回可打印的字符串。如果未提供任何参数,则返回空字符串''

In short, the goal of __repr__ is to be unambiguous and __str__ is to be readable.

Here is a good example:

>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2012-03-14 09:21:58.130922'
>>> repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'

Read this documentation for repr:

repr(object)

Return a string containing a printable representation of an object. This is the same value yielded by conversions (reverse quotes). It is sometimes useful to be able to access this operation as an ordinary function. For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a __repr__() method.

Here is the documentation for str:

str(object='')

Return a string containing a nicely printable representation of an object. For strings, this returns the string itself. The difference with repr(object) is that str(object) does not always attempt to return a string that is acceptable to eval(); its goal is to return a printable string. If no argument is given, returns the empty string, ''.


回答 5

__str____repr__Python 和有什么不一样?

__str__(读为“ dunder(双下划线)字符串”)和__repr__(读为“ dunder-repper”(对于“表示形式”))都是根据对象状态返回字符串的特殊方法。

__repr__如果__str__丢失,则提供备份行为。

因此,首先应该编写一个__repr__,使您可以从返回的字符串中重新实例化一个等效的对象,例如,使用eval或通过在Python Shell中的逐字符键入字符。

在以后的任何时候,只要__str__有人认为有必要,就可以为该实例的用户可读的字符串表示形式编写一个。

__str__

如果打印对象,或将其传递给formatstr.formatstr,则如果__str__定义了方法,则将调用该方法,否则__repr__将使用该方法。

__repr__

__repr__方法由内置函数调用,repr并且是在评估返回对象的表达式时在python shell上回显的方法。

由于它为提供了备份__str__,如果您只能写一个,请从__repr__

这是关于的内置帮助repr

repr(...)
    repr(object) -> string

    Return the canonical string representation of the object.
    For most object types, eval(repr(object)) == object.

也就是说,对于大多数对象,如果键入所打印的内容repr,则应该能够创建等效对象。但这不是默认的实现。

默认实现 __repr__

默认对象__repr__是(C Python source)类似:

def __repr__(self):
    return '<{0}.{1} object at {2}>'.format(
      self.__module__, type(self).__name__, hex(id(self)))

这意味着默认情况下,您将打印对象所属的模块,类名以及其在内存中位置的十六进制表示形式,例如:

<__main__.Foo object at 0x7f80665abdd0>

这些信息不是很有用,但是无法得出如何准确地创建任何给定实例的规范表示的方法,它总比没有好,至少告诉我们如何在内存中唯一标识它。

怎么__repr__有用?

让我们看看使用Python Shell和datetime对象有多么有用。首先,我们需要导入datetime模块:

import datetime

如果datetime.now在外壳中调用,我们将看到重新创建等效的datetime对象所需的一切。这是由datetime创建的__repr__

>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)

如果我们打印日期时间对象,则会看到一种很好的人类可读(实际上是ISO)格式。这是通过datetime的实现的__str__

>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951

重新创建丢失的对象是一件简单的事情,因为我们没有通过复制和粘贴从__repr__输出中将其分配给变量,然后进行打印,然后将其与其他对象存储在相同的人类可读输出中:

>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180

我该如何实施?

在开发过程中,如果可能的话,您将希望能够以相同状态再现对象。例如,这就是datetime对象的定义方式__repr__Python源)。由于复制此类对象所需的所有属性,它相当复杂:

def __repr__(self):
    """Convert to formal string, for repr()."""
    L = [self._year, self._month, self._day,  # These are never zero
         self._hour, self._minute, self._second, self._microsecond]
    if L[-1] == 0:
        del L[-1]
    if L[-1] == 0:
        del L[-1]
    s = "%s.%s(%s)" % (self.__class__.__module__,
                       self.__class__.__qualname__,
                       ", ".join(map(str, L)))
    if self._tzinfo is not None:
        assert s[-1:] == ")"
        s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
    if self._fold:
        assert s[-1:] == ")"
        s = s[:-1] + ", fold=1)"
    return s

如果希望对象具有更易理解的表示形式,则可以执行__str__下一步。这是datetime对象(Python源)的实现方式__str__,它很容易实现,因为它已经具有以ISO格式显示它的功能:

def __str__(self):
    "Convert to string, for str()."
    return self.isoformat(sep=' ')

设置__repr__ = __str__

这是对这里提出设置的另一个答案的批评__repr__ = __str__

设置__repr__ = __str__很愚蠢- __repr__是一个后备功能__str____repr__在编写a之前应先写一个供开发人员在调试中使用的a __str__

你需要一个__str__只有当你需要的对象的文本表示。

结论

__repr__为您编写的对象进行定义,以便您和其他开发人员在开发过程中使用它时可以得到一个可重现的示例。定义__str__何时需要其人类可读的字符串表示形式。

What is the difference between __str__ and __repr__ in Python?

__str__ (read as “dunder (double-underscore) string”) and __repr__ (read as “dunder-repper” (for “representation”)) are both special methods that return strings based on the state of the object.

__repr__ provides backup behavior if __str__ is missing.

So one should first write a __repr__ that allows you to reinstantiate an equivalent object from the string it returns e.g. using eval or by typing it in character-for-character in a Python shell.

At any time later, one can write a __str__ for a user-readable string representation of the instance, when one believes it to be necessary.

__str__

If you print an object, or pass it to format, str.format, or str, then if a __str__ method is defined, that method will be called, otherwise, __repr__ will be used.

__repr__

The __repr__ method is called by the builtin function repr and is what is echoed on your python shell when it evaluates an expression that returns an object.

Since it provides a backup for __str__, if you can only write one, start with __repr__

Here’s the builtin help on repr:

repr(...)
    repr(object) -> string

    Return the canonical string representation of the object.
    For most object types, eval(repr(object)) == object.

That is, for most objects, if you type in what is printed by repr, you should be able to create an equivalent object. But this is not the default implementation.

Default Implementation of __repr__

The default object __repr__ is (C Python source) something like:

def __repr__(self):
    return '<{0}.{1} object at {2}>'.format(
      self.__module__, type(self).__name__, hex(id(self)))

That means by default you’ll print the module the object is from, the class name, and the hexadecimal representation of its location in memory – for example:

<__main__.Foo object at 0x7f80665abdd0>

This information isn’t very useful, but there’s no way to derive how one might accurately create a canonical representation of any given instance, and it’s better than nothing, at least telling us how we might uniquely identify it in memory.

How can __repr__ be useful?

Let’s look at how useful it can be, using the Python shell and datetime objects. First we need to import the datetime module:

import datetime

If we call datetime.now in the shell, we’ll see everything we need to recreate an equivalent datetime object. This is created by the datetime __repr__:

>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)

If we print a datetime object, we see a nice human readable (in fact, ISO) format. This is implemented by datetime’s __str__:

>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951

It is a simple matter to recreate the object we lost because we didn’t assign it to a variable by copying and pasting from the __repr__ output, and then printing it, and we get it in the same human readable output as the other object:

>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180

How do I implement them?

As you’re developing, you’ll want to be able to reproduce objects in the same state, if possible. This, for example, is how the datetime object defines __repr__ (Python source). It is fairly complex, because of all of the attributes needed to reproduce such an object:

def __repr__(self):
    """Convert to formal string, for repr()."""
    L = [self._year, self._month, self._day,  # These are never zero
         self._hour, self._minute, self._second, self._microsecond]
    if L[-1] == 0:
        del L[-1]
    if L[-1] == 0:
        del L[-1]
    s = "%s.%s(%s)" % (self.__class__.__module__,
                       self.__class__.__qualname__,
                       ", ".join(map(str, L)))
    if self._tzinfo is not None:
        assert s[-1:] == ")"
        s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
    if self._fold:
        assert s[-1:] == ")"
        s = s[:-1] + ", fold=1)"
    return s

If you want your object to have a more human readable representation, you can implement __str__ next. Here’s how the datetime object (Python source) implements __str__, which it easily does because it already has a function to display it in ISO format:

def __str__(self):
    "Convert to string, for str()."
    return self.isoformat(sep=' ')

Set __repr__ = __str__?

This is a critique of another answer here that suggests setting __repr__ = __str__.

Setting __repr__ = __str__ is silly – __repr__ is a fallback for __str__ and a __repr__, written for developers usage in debugging, should be written before you write a __str__.

You need a __str__ only when you need a textual representation of the object.

Conclusion

Define __repr__ for objects you write so you and other developers have a reproducible example when using it as you develop. Define __str__ when you need a human readable string representation of it.


回答 6

在Hans Petter Langtangen 撰写的《用于计算科学Python脚本》一书的第358页中,明确指出:

  • 所述__repr__在所述物体的完整字符串表示目标;
  • __str__是返回一个字符串,不错的打印。

所以,我更喜欢将它们理解为

  • repr =复制
  • str =字符串(表示形式)

从用户的角度来看,尽管这是我在学习python时的一个误解。

在同一页面上还提供了一个很小但很好的示例,如下所示:

In [38]: str('s')
Out[38]: 's'

In [39]: repr('s')
Out[39]: "'s'"

In [40]: eval(str('s'))
Traceback (most recent call last):

  File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
    eval(str('s'))

  File "<string>", line 1, in <module>

NameError: name 's' is not defined


In [41]: eval(repr('s'))
Out[41]: 's'

On page 358 of the book Python scripting for computational science by Hans Petter Langtangen, it clearly states that

  • The __repr__ aims at a complete string representation of the object;
  • The __str__ is to return a nice string for printing.

So, I prefer to understand them as

  • repr = reproduce
  • str = string (representation)

from the user’s point of view although this is a misunderstanding I made when learning python.

A small but good example is also given on the same page as follows:

Example

In [38]: str('s')
Out[38]: 's'

In [39]: repr('s')
Out[39]: "'s'"

In [40]: eval(str('s'))
Traceback (most recent call last):

  File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
    eval(str('s'))

  File "<string>", line 1, in <module>

NameError: name 's' is not defined


In [41]: eval(repr('s'))
Out[41]: 's'

回答 7

除了给出的所有答案外,我想补充几点:

__repr__()当您在交互式python控制台上简单地写对象名称并按Enter时,将调用1)。

2)__str__()在带print语句的对象上使用时被调用。

3)如果__str__丢失,则打印并使用对象str()调用__repr__()进行任何功能。

4)__str__()容器,当被调用时将执行__repr__()其所包含元素的方法。

5)str()在内部调用__str__()可能会在没有基本情况的情况下递归,并且最大递归深度会出错。

6)__repr__()可以调用repr(),它将尝试自动避免无限递归,将表示的对象替换为...

Apart from all the answers given, I would like to add few points :-

1) __repr__() is invoked when you simply write object’s name on interactive python console and press enter.

2) __str__() is invoked when you use object with print statement.

3) In case, if __str__ is missing, then print and any function using str() invokes __repr__() of object.

4) __str__() of containers, when invoked will execute __repr__() method of its contained elements.

5) str() called within __str__() could potentially recurse without a base case, and error on maximum recursion depth.

6) __repr__() can call repr() which will attempt to avoid infinite recursion automatically, replacing an already represented object with ....


回答 8

老实说,eval(repr(obj))从未使用过。如果发现自己正在使用它,则应该停止操作,因为这样做eval很危险,而字符串是序列化对象(pickle替代使用)的效率很低的方法。

因此,我建议设置__repr__ = __str__。原因是str(list)调用repr元素(我认为这是Python 3未能解决的Python最大设计缺陷之一)。实际repr输出可能不会非常有用print [your, objects]

为了证明这一点,以我的经验,该repr函数最有用的用例是将一个字符串放入另一个字符串中(使用字符串格式)。这样,您不必担心转义引号或其他内容。但是请注意,这里没有eval发生任何事情。

In all honesty, eval(repr(obj)) is never used. If you find yourself using it, you should stop, because eval is dangerous, and strings are a very inefficient way to serialize your objects (use pickle instead).

Therefore, I would recommend setting __repr__ = __str__. The reason is that str(list) calls repr on the elements (I consider this to be one of the biggest design flaws of Python that was not addressed by Python 3). An actual repr will probably not be very helpful as the output of print [your, objects].

To qualify this, in my experience, the most useful use case of the repr function is to put a string inside another string (using string formatting). This way, you don’t have to worry about escaping quotes or anything. But note that there is no eval happening here.


回答 9

简而言之:

__str__用于显示对象的字符串表示形式,以方便他人阅读

__repr__用于显示的字符串表示对象。

假设我要创建一个Fraction类,其中分数的字符串表示形式为“(1/2)”,而对象(分数类)将表示为“分数(1,2)”

因此,我们可以创建一个简单的Fraction类:

class Fraction:
    def __init__(self, num, den):
        self.__num = num
        self.__den = den

    def __str__(self):
        return '(' + str(self.__num) + '/' + str(self.__den) + ')'

    def __repr__(self):
        return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'



f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)

To put it simply:

__str__ is used in to show a string representation of your object to be read easily by others.

__repr__ is used to show a string representation of the object.

Let’s say I want to create a Fraction class where the string representation of a fraction is ‘(1/2)’ and the object (Fraction class) is to be represented as ‘Fraction (1,2)’

So we can create a simple Fraction class:

class Fraction:
    def __init__(self, num, den):
        self.__num = num
        self.__den = den

    def __str__(self):
        return '(' + str(self.__num) + '/' + str(self.__den) + ')'

    def __repr__(self):
        return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'



f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)

回答 10

来自effbot 的(非官方)Python参考Wiki(归档副本)

__str__计算‘正规’的对象的字符串表示这不同于。__repr__在它不必须是一个有效的Python表达式:一个更方便或简洁表示可以被代替使用。

From an (An Unofficial) Python Reference Wiki (archive copy) by effbot:

__str__computes the “informal” string representation of an object. This differs from __repr__ in that it does not have to be a valid Python expression: a more convenient or concise representation may be used instead.


回答 11

str -从给定的对象创建一个新的字符串对象。

repr -返回对象的规范字符串表示形式。

区别:

str():

  • 使对象可读
  • 为最终用户生成输出

repr():

  • 需要复制对象的代码
  • 为开发人员生成输出

str – Creates a new string object from the given object.

repr – Returns the canonical string representation of the object.

The differences:

str():

  • makes object readable
  • generates output for end-user

repr():

  • needs code that reproduces object
  • generates output for developer

回答 12

其他答案中缺少的一个方面。的确,该模式通常是:

  • 目标__str__:人类可读
  • 目标__repr__:明确,可能通过机器读取eval

不幸的是,这种区别是有缺陷的,因为Python REPL和IPython都__repr__用于在REPL控制台中打印对象(请参阅PythonIPython的相关问题)。因此,以交互式控制台工作为目标的项目(例如Numpy或Pandas)已经开始忽略上述规则,__repr__而是提供了易于理解的实现方式。

One aspect that is missing in other answers. It’s true that in general the pattern is:

  • Goal of __str__: human-readable
  • Goal of __repr__: unambiguous, possibly machine-readable via eval

Unfortunately, this differentiation is flawed, because the Python REPL and also IPython use __repr__ for printing objects in a REPL console (see related questions for Python and IPython). Thus, projects which are targeted for interactive console work (e.g., Numpy or Pandas) have started to ignore above rules and provide a human-readable __repr__ implementation instead.


回答 13

摘自Fluent Python一书:

Python对象的基本要求是提供其自身的可用字符串表示形式,一种用于调试和记录,另一种用于呈现给最终用户。这就是为什么
特殊方法__repr____str__存在于数据模型中的原因。

From the book Fluent Python:

A basic requirement for a Python object is to provide usable string representations of itself, one used for debugging and logging, another for presentation to end users. That is why the
special methods __repr__ and __str__ exist in the data model.


回答 14

出色的答案已经涵盖了__str__和之间的区别__repr__,对我而言,这归结为前者甚至对于最终用户而言都是可读的,而后者对开发人员则尽可能有用。鉴于此,我发现的默认实现__repr__常常无法实现此目标,因为它忽略了对开发人员有用的信息。

出于这个原因,如果我有一个简单的方法__str__,我通常会尝试通过以下方法使两个方面都达到最佳:

def __repr__(self):
    return '{0} ({1})'.format(object.__repr__(self), str(self))

Excellent answers already cover the difference between __str__ and __repr__, which for me boils down to the former being readable even by an end user, and the latter being as useful as possible to developers. Given that, I find that the default implementation of __repr__ often fails to achieve this goal because it omits information useful to developers.

For this reason, if I have a simple enough __str__, I generally just try to get the best of both worlds with something like:

def __repr__(self):
    return '{0} ({1})'.format(object.__repr__(self), str(self))

回答 15

要记住的重要一件事是容器的__str__使用包含对象__repr__

>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"

Python主张明确性胜于可读性__str__调用tuple调用包含的对象’ __repr__,即对象的“正式”表示形式。尽管正式表示比非正式表示更难读,但它对歧义没有任何歧义,并且更强大。

One important thing to keep in mind is that container’s __str__ uses contained objects’ __repr__.

>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"

Python favors unambiguity over readability, the __str__ call of a tuple calls the contained objects’ __repr__, the “formal” representation of an object. Although the formal representation is harder to read than an informal one, it is unambiguous and more robust against bugs.


回答 16

简而言之:

class Demo:
  def __repr__(self):
    return 'repr'
  def __str__(self):
    return 'str'

demo = Demo()
print(demo) # use __str__, output 'str' to stdout

s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'

import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout

from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'

In a nutshell:

class Demo:
  def __repr__(self):
    return 'repr'
  def __str__(self):
    return 'str'

demo = Demo()
print(demo) # use __str__, output 'str' to stdout

s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'

import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout

from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'

回答 17

>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')

原始数据print()的结果decimal.Decimal(23) / decimal.Decimal("1.05")被打印时被调用;此输出为字符串形式,可以使用来实现__str__()。如果仅输入表达式,我们将得到一个decimal.Decimal输出-该输出采用可通过表示的形式__repr__()。所有Python对象都有两种输出形式。字符串形式被设计为易于阅读。表示形式旨在产生输出,如果将其提供给Python解释器,则该输出将(如果可能)再现所表示的对象。

>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')

When print() is called on the result of decimal.Decimal(23) / decimal.Decimal("1.05") the raw number is printed; this output is in string form which can be achieved with __str__(). If we simply enter the expression we get a decimal.Decimal output — this output is in representational form which can be achieved with __repr__(). All Python objects have two output forms. String form is designed to be human-readable. The representational form is designed to produce output that if fed to a Python interpreter would (when possible) reproduce the represented object.


回答 18

__str__可以通过调用在对象上调用,str(obj)并且应返回人类可读的字符串。

__repr__可以通过调用在对象上调用,repr(obj)并且应该返回内部对象(对象字段/属性)

此示例可能会有所帮助:

class C1:pass

class C2:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")

class C3:        
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")

class C4:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")


ci1 = C1()    
ci2 = C2()  
ci3 = C3()  
ci4 = C4()

print(ci1)       #<__main__.C1 object at 0x0000024C44A80C18>
print(str(ci1))  #<__main__.C1 object at 0x0000024C44A80C18>
print(repr(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(ci2)       #C2 class str
print(str(ci2))  #C2 class str
print(repr(ci2)) #<__main__.C2 object at 0x0000024C44AE12E8>
print(ci3)       #C3 class repr
print(str(ci3))  #C3 class repr
print(repr(ci3)) #C3 class repr
print(ci4)       #C4 class str 
print(str(ci4))  #C4 class str 
print(repr(ci4)) #C4 class repr

__str__ can be invoked on an object by calling str(obj) and should return a human readable string.

__repr__ can be invoked on an object by calling repr(obj) and should return internal object (object fields/attributes)

This example may help:

class C1:pass

class C2:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")

class C3:        
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")

class C4:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")


ci1 = C1()    
ci2 = C2()  
ci3 = C3()  
ci4 = C4()

print(ci1)       #<__main__.C1 object at 0x0000024C44A80C18>
print(str(ci1))  #<__main__.C1 object at 0x0000024C44A80C18>
print(repr(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(ci2)       #C2 class str
print(str(ci2))  #C2 class str
print(repr(ci2)) #<__main__.C2 object at 0x0000024C44AE12E8>
print(ci3)       #C3 class repr
print(str(ci3))  #C3 class repr
print(repr(ci3)) #C3 class repr
print(ci4)       #C4 class str 
print(str(ci4))  #C4 class str 
print(repr(ci4)) #C4 class repr

回答 19

理解__str____repr__直观,永久地将它们区分开。

__str__返回给定对象的字符串伪装体,以使眼睛可读
__repr__

在一个例子中看到它

In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form

至于 __repr__

In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.

我们可以__repr__方便地对结果进行算术运算。

In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
    ...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)

如果将操作应用于 __str__

In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'

只返回错误。

另一个例子。

In [36]: str('string_body')
Out[36]: 'string_body' # in string form

In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside

希望这可以帮助您建立具体的基础,以探索更多的答案。

Understand __str__ and __repr__ intuitively and permanently distinguish them at all.

__str__ return the string disguised body of a given object for readable of eyes
__repr__ return the real flesh body of a given object (return itself) for unambiguity to identify.

See it in an example

In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form

As to __repr__

In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.

We can do arithmetic operation on __repr__ results conveniently.

In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
    ...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)

if apply the operation on __str__

In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'

Returns nothing but error.

Another example.

In [36]: str('string_body')
Out[36]: 'string_body' # in string form

In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside

Hope this help you build concrete grounds to explore more answers.


回答 20

  1. __str__必须返回字符串对象,而__repr__可以返回任何python表达式。
  2. 如果__str__缺少实现,则将__repr__功能用作备用。如果__repr__缺少函数实现,则没有回退。
  3. 如果__repr__函数返回对象的字符串表示形式,则可以跳过__str__函数的实现。

资料来源:https : //www.journaldev.com/22460/python-str-repr-functions

  1. __str__ must return string object whereas __repr__ can return any python expression.
  2. If __str__ implementation is missing then __repr__ function is used as fallback. There is no fallback if __repr__ function implementation is missing.
  3. If __repr__ function is returning String representation of the object, we can skip implementation of __str__ function.

Source: https://www.journaldev.com/22460/python-str-repr-functions


回答 21

__repr__用于除printstr方法(__str__定义a时!)之外的所有地方

__repr__ is used everywhere, except by print and str methods (when a __str__is defined !)


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。