官方文档概述了如何处理 __repr__:
由 repr() 内置函数调用,计算对象的“官方”字符串表示形式。如果可能的话,
这应该看起来像一个有效的 Python 表达式,可以用于创建一个具有相同值的对象
(给定适当的环境)。如果不可能,应返回形如 <...some useful description...>
的字符串。返回值必须是字符串对象。如果一个类定义了 __repr__() 而没有定义
__str__(),那么在需要这个类实例的“非正式”字符串表示时也会使用 __repr__()。
通常用于调试,因此表示形式应具有信息丰富和明确不误的特点。
Python 3 __repr__
文档
列表、字符串、集合、元组和字典在其 __repr__ 方法中打印出其整个集合。
您当前的代码看起来完全遵循文档所建议的示例。但我建议将您的 __init__ 方法更改为以下方式:
class MyCollection:
def __init__(self, objects=None):
if objects is None:
objects = []
self._objects = objects
def __repr__(self):
return f"MyCollection({self._objects})"
通常情况下,您应该避免将可变对象用作默认参数。从技术上讲,由于使用了extend方法(它会复制列表),所以它仍然可以正常工作,但是Python的文档仍建议您避免这样做。
好的编程实践是不要使用可变对象作为默认值。相反,使用None作为默认值,在函数内部检查参数是否为None,如果是,则创建一个新的列表/字典/任何其他对象。
https://docs.python.org/zh-cn/3/faq/programming.html#why-are-default-values-shared-between-objects
如果您对另一个库如何进行不同处理感兴趣,Numpy数组的repr仅在数组长度大于1,000时显示前三个和最后三个项。它还使所有项目都使用相同数量的空间进行格式化(在下面的示例中,1000占用四个空格,因此必须用三个更多的空格填充0以匹配)。
>>> repr(np.array([i for i in range(1001)]))
'array([ 0, 1, 2, ..., 998, 999, 1000])'
要模仿这个numpy数组样式,您可以在您的类中实现一个像下面这样的__repr__方法:
要模仿这个 numpy 数组样式,您可以在您的类中实现一个像这样的 __repr__ 方法:
class MyCollection:
def __init__(self, objects=None):
if objects is None:
objects = []
self._objects = objects
def __repr__(self):
if len(self._objects) < 1000:
return f"MyCollection({self._objects})"
else:
items_to_display = self._objects[:3] + self._objects[-3:]
max_length_repr = max(items_to_display, key=lambda x: len(repr(x)))
padding = len(repr(max_length_repr))
values = [repr(item).rjust(padding) for item in items_to_display]
values.insert(3, '...')
array_as_string = ', '.join(values)
return f"MyCollection([{array_as_string}])"
>>> repr(MyCollection([1,2,3,4]))
'MyCollection([1, 2, 3, 4])'
>>> repr(MyCollection([i for i in range(1001)]))
'MyCollection([ 0, 1, 2, ..., 998, 999, 1000])'
list
确实会打印出所有内容。我还没有测试其他内置容器,但是 numpy 的ndarray
会缩短它的 repr(我知道,不是标准库,但仍然...)。 - abeyrepr
的目的并不是制造出看起来好看的东西,而是为了帮助调试。将缩短算法保存到__str__
或自定义方法中。 - chepner