【问题标题】:What is the purpose of __str__ and __repr__? [duplicate]__str__ 和 __repr__ 的目的是什么? [复制]
【发布时间】:2011-04-11 02:30:23
【问题描述】:

我真的不明白 __str____repr__ 在 Python 中用在哪里。我的意思是,我知道__str__ 返回一个对象的字符串表示。但我为什么需要那个?在什么用例场景中?另外,我读到了__repr__的用法

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

【问题讨论】:

标签: python


【解决方案1】:

__repr__

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

__str__

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

如果您有一个类,请使用__str__,并且无论何时将该对象用作字符串的一部分,您都需要一个信息性/非正式的输出。例如。您可以为 Django 模型定义 __str__ 方法,然后在 Django 管理界面中呈现。而不是像<Model object> 这样的东西,你会得到一个人的名字和姓氏、事件的名称和日期等。


__repr____str__ 相似,实际上有时相等(来自标准库中sets.py 中的BaseSet 类的示例):

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__

【讨论】:

  • 谢谢!这正是我想要的!
  • `return self._repr()` 做了什么,当我运行代码并试图理解它时说 __repr__() 只接受一个参数。
  • 那么,我可以使用__repr__ 代替__str__ django 吗?
【解决方案2】:

蚱蜢,如有疑问go to the mountainread the Ancient Texts。在它们中你会发现 __repr__() 应该:

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

【讨论】:

  • -1 因为这甚至没有尝试回答实际问题,这就是用例。
  • @Scott:你是对的。但是,actual question 再次表明绝对没有尝试首先访问主要文档。问一个表明您已经尝试自己回答但仍然对它的某些方面有些困惑的问题是一回事,而发布这样的问题则完全是另一回事。只需在他的主题行中输入一个新问题,就表明前 6 个建议的 SO 线程中有 5 个会回答他的问题,但他不会被打扰。我没有完全给他一个 lmgtfy 的答案,但我很受诱惑。
  • 实际上他确实说过他读过__repr__,官方文档并没有真正回答你为什么要使用它的问题,仅仅因为一个问题在别处得到了回答'这不是一个很好的理由,它也不能在 SO 上得到回答(因为谷歌搜索经常会把你带回这里!)如果你认为这个问题不值得回答,那么你就不能回答它,尽管在这个情况下,我同意它已经在 SO 上很好地涵盖了,因此链接到重复项将是一个适当的响应。
  • 其实你错了。文档明确说明了为什么要使用它,即:“这通常用于调试,因此表示信息丰富且明确是很重要的。”我已经看到太多的论坛(论坛?)在帮助吸血鬼的重压下沉没,看到它开始流传下去让我很痛苦。至于链接到其他明显的 SO 答案,这是在您输入主题行时启动的建议机制的全部目的,但他选择忽略所有建议。 QED 和 PDQ 也是如此。
  • 好吧,文档仍然没有说明 如何 使用它进行调试,但我真的不打算为此争论。我们至少同意你的回答没有解决这个问题,所以我的 -1 对我来说仍然是合理的。如果问题写得不好/重复/琐碎,那么您可以帮助改进问题,链接到重复项,或者简单地对问题投反对票。我认为我在这里的主要反对意见是答案应该试图回答这个问题——还有其他批评这个问题的机制。我现在就闭嘴,因为我认为我们都有更好的事情要做。
【解决方案3】:

您经常使用它们的一个地方是在交互式会话中。如果你打印一个对象,那么它的__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__ 返回相同的值也很正常(当然对于内置类型)。

【讨论】:

  • 感谢您的示例,让我更好地了解默认情况下使用它的位置
【解决方案4】:

在前面的答案的基础上建立并展示更多示例。如果使用得当,strrepr 之间的区别就很明显了。简而言之,repr 应该返回一个可以复制粘贴的字符串以重建对象的确切状态,而str 对于loggingobserving 调试结果很有用。下面是一些示例,可以查看一些已知库的不同输出。

日期时间

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)

麻木

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 再次可直接使用。

自定义 Vector3 示例

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

要记住一件事,如果str 未定义但reprstr 将自动调用repr。所以,至少定义repr总是好的

【讨论】:

    【解决方案5】:

    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
    

    【讨论】:

      【解决方案6】:

      让我们有一个没有__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

      【讨论】:

        【解决方案7】:

        strrepr 都是表示的方式。您可以在编写课程时使用它们。

        class Fraction:
        def __init__(self, n, d):
            self.n = n
            self.d = d
        def __repr__(self):
            return "{}/{}".format(self.n, self.d)
        

        例如,当我打印它的一个实例时,它会返回一些东西。

        print(Fraction(1, 2))
        

        结果

        1/2
        

        同时

        class Fraction:
        def __init__(self, n, d):
            self.n = n
            self.d = d
        def __str__(self):
            return "{}/{}".format(self.n, self.d)
        print(Fraction(1, 2))
        

        也会导致

        1/2
        

        但是如果两个都写呢,python用的是哪一个呢?

        class Fraction:
        def __init__(self, n, d):
            self.n = n
            self.d = d
        def __str__(self):
            return "str"
        def __repr__(self):
            return "repr"
        
        print(Fraction(None, None))
        

        这会导致

        str
        

        所以python实际上是用str方法而不是repr方法写的。

        【讨论】:

          【解决方案8】:

          假设你有一个类并希望检查一个实例,你发现打印并没有提供太多有用的信息

          class Person:
              def __init__(self, name, age):
                  self.name = name
                  self.age = age
          
          
          p1 = Person("John", 36)
          print(p1)  # <__main__.Animal object at 0x7f9060250410>
          

          现在看到一个带有 str 的类,它显示实例信息,而使用 repr 你甚至不需要打印。不错吗?

          class Animal:
              def __init__(self, color, age, breed):
                  self.color = color
                  self.age = age
                  self.breed = breed
          
              def __str__(self):
                  return f"{self.color} {self.breed} of age {self.age}"
          
              def __repr__(self):
                  return f"repr : {self.color} {self.breed} of age {self.age}"
          
          
          a1 = Animal("Red", 36, "Dog")
          a1  # repr : Red Dog of age 36
          print(a1)  # Red Dog of age 36
          

          【讨论】:

            猜你喜欢
            • 2013-08-25
            • 2020-02-07
            • 2016-06-14
            • 1970-01-01
            • 1970-01-01
            • 2018-11-23
            • 2019-04-05
            • 2013-01-28
            相关资源
            最近更新 更多