【问题标题】:Python predefined __str__ method behaves unexpectedly [duplicate]Python预定义的__str__方法行为异常[重复]
【发布时间】:2021-06-27 18:43:01
【问题描述】:

下面是一个简单的 Python 类的定义。

class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade

    def __str__(self):
        return self.name

如您所见,我们重写了__str__ 方法以返回学生的姓名。例如,如果我声明一个变量 x = Student("Trevor", 7) 并随后调用 print(x),我会在控制台中看到输出 Trevor。一切都很好。

但是,如果我执行下面的 sn-p,会发生出乎意料的事情,以至于它几乎让我相信我们生活在一个模拟中,没有什么是真实的。

s1 = Student("James", 11)
s2 = Student("Charlie", 8)
s3 = Student("Alice", 9)
s4 = Student("Dana", 12)
students = [s1, s2, s3, s4]
print(students)

我的 Java 大脑预计输出是 [James, Charlie, Alice, Dana],但我看到的是 [<__main__.Student object at 0x00A7E6D0>, <__main__.Student object at 0x00AFB310>, <__main__.Student object at 0x00AFBB68>, <__main__.Student object at 0x00AFBAD8>]

这怎么可能?怎么可能?我是真的吗?你是真的吗?我只是不明白。如何?为什么?为什么?

【问题讨论】:

  • 也许列表的__str__ 方法没有在它的元素上调用__str__。但是,您可以手动执行此操作,它会起作用。
  • 大多数容器类型(例如列表)的__str__() 是由其元素的__repr__() 构建的,而不是它们的__str__()。您可以将__repr__ = __str__ 放在类定义的底部,以便对两者使用相同的方法。
  • ...或者只定义__repr____str__ 如果未定义将回退到它...

标签: python python-3.x


【解决方案1】:

您的假设that list recursively calls str on its elements is wronglist调用repr,通过魔术方法__repr__实现:

>>> class Foo:
...   def __init__(self, n):
...       self.n = n
...   def __repr__(self):
...       return self.n
...
>>> [Foo('a'), Foo('b')]
[a, b]
>>> print(_)
[a, b]

然而,__repr__ 方法的目标是不是在这种情况下返回一个纯字符串,而是一个可用于重新创建对象的表示。

【讨论】:

  • 你可能想提一下,默认情况下,str 使用 repr,而不是相反
  • 非常有趣。这实际上很有意义。实际上,您只会出于调试目的直接打印一个列表。因此,最好在元素上调用__repr__ 而不是__str__。此外,python 列表没有类型化,使得元素的“官方”字符串表示更加相关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 2014-10-23
  • 2010-12-25
  • 2020-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多