精美的印刷¶
除了语法突出显示外,Rich还将格式化(即 pretty print )容器,如列表、词典和集合。
运行以下命令以查看打印输出的示例:
python -m rich.pretty
请注意,输出将如何更改以适应终端宽度。
Pprint方法¶
这个 pprint()
方法提供了更多的参数,您可以使用它们来调整对象的打印方式。以下是导入它的方法::
>>> from rich.pretty import pprint
>>> pprint(locals())
缩进辅助线¶
里奇会画画 indent guides 以突出显示数据结构的缩进级别。这些可以使读取嵌套更深的输出变得更容易。默认情况下,pprint方法启用缩进辅助线。您可以设置 indent_guides=False
以禁用此功能。
全部展开¶
Rich在扩展数据结构方面相当保守,并将尝试尽可能多地适应每一行。如果愿意,您可以告诉Rich通过设置来完全扩展所有数据结构 expand_all=True
。以下是一个示例:
>>> pprint(["eggs", "ham"], expand_all=True)
截断相当不错的产出¶
很长的数据结构可能很难阅读,您可能会发现自己在终端的多个页面中滚动以找到您感兴趣的数据。Rich可以截断容器和长字符串,为您提供概述,而不会淹没您的码头。
如果您将 max_length
argument to an integer, Rich will truncate containers with more than the given number of elements. If data is truncated, Rich will display an ellipsis ...
以及未显示的元素的数量。
以下是一个示例:
>>> pprint(locals(), max_length=2)
如果您将 max_string
参数设置为整数,则Rich将截断该长度的字符串。截断的字符串将追加未显示的字符数。以下是一个示例:
>>> pprint("Where there is a Will, there is a Way", max_string=21)
渲染效果非常好¶
Rich提供了一种 Pretty
类,您可以使用该类将精美的打印数据插入到另一个可呈现的。
下面的示例在一个简单的面板中显示漂亮的打印数据:
from rich import print
from rich.pretty import Pretty
from rich.panel import Panel
pretty = Pretty(locals())
panel = Panel(pretty)
print(panel)
有大量选项可以调整漂亮的格式,请参阅 Pretty
有关详情,请参阅。
富REPR协议¶
Rich能够在语法上突出显示任何输出,但格式化仅限于内置容器、数据类和Rich知道的其他对象,例如由 attrs 类库。若要向自定义对象添加丰富的格式设置功能,可以实现 rich repr protocol 。
运行以下命令以查看Rich Repr协议可以生成的示例:
python -m rich.repr
首先,让我们看一个可能受益于Rich Repr::
class Bird:
def __init__(self, name, eats=None, fly=True, extinct=False):
self.name = name
self.eats = list(eats) if eats else []
self.fly = fly
self.extinct = extinct
def __repr__(self):
return f"Bird({self.name!r}, eats={self.eats!r}, fly={self.fly!r}, extinct={self.extinct!r})"
BIRDS = {
"gull": Bird("gull", eats=["fish", "chips", "ice cream", "sausage rolls"]),
"penguin": Bird("penguin", eats=["fish"], fly=False),
"dodo": Bird("dodo", eats=["fruit"], fly=False, extinct=True)
}
print(BIRDS)
此脚本的结果将是::
{'gull': Bird('gull', eats=['fish', 'chips', 'ice cream', 'sausage rolls'], fly=True, extinct=False), 'penguin': Bird('penguin', eats=['fish'], fly=False, extinct=False), 'dodo': Bird('dodo', eats=['fruit'], fly=False, extinct=True)}
输出足够长,可以换到下一行,这可能会使其难以阅读。REPR字符串是信息性的,但有点冗长,因为它们包含默认参数。如果我们与Rich一起打印,情况会有所改善::
{
'gull': Bird('gull', eats=['fish', 'chips', 'ice cream', 'sausage rolls'],
fly=True, extinct=False),
'penguin': Bird('penguin', eats=['fish'], fly=False, extinct=False),
'dodo': Bird('dodo', eats=['fruit'], fly=False, extinct=True)
}
Rich知道如何格式化容器DICT,但是REPR字符串仍然很冗长,并且输出有一些换行(假设终端是80个字符)。
我们可以通过添加以下内容来解决这两个问题 __rich_repr__
方法:
def __rich_repr__(self):
yield self.name
yield "eats", self.eats
yield "fly", self.fly, True
yield "extinct", self.extinct, False
现在,如果我们使用Rich打印相同的对象,我们将看到以下内容:
{
'gull': Bird(
'gull',
eats=['fish', 'chips', 'ice cream', 'sausage rolls']
),
'penguin': Bird('penguin', eats=['fish'], fly=False),
'dodo': Bird('dodo', eats=['fruit'], fly=False, extinct=True)
}
省略了缺省参数,并且输出的格式设置得很好。即使我们在终端中的空间较小,或者我们的对象是深度嵌套的数据结构的一部分,输出仍可读:
{
'gull': Bird(
'gull',
eats=[
'fish',
'chips',
'ice cream',
'sausage rolls'
]
),
'penguin': Bird(
'penguin',
eats=['fish'],
fly=False
),
'dodo': Bird(
'dodo',
eats=['fruit'],
fly=False,
extinct=True
)
}
您可以添加一个 __rich_repr__
方法绑定到任何类以启用Rich Formatting。此方法应返回可迭代的元组。您可以返回元组列表,但使用 yield
关键字,使其成为 generator 。
每个元组指定输出中的一个元素。
yield value
将生成位置参数。yield name, value
将生成关键字参数。yield name, value, default
将生成关键字参数 ifvalue
不等于default
。
如果您使用 None
作为 name
,那么它也将被视为位置参数,以支持具有 tuple
立场论据。
您还可以告诉Rich生成 angular bracket 样式的REPR,通常用于没有简单的方法来重新创建对象的构造函数的地方。为此,请设置Function属性 "angular"
至 True
紧接在您的 __rich_repr__
方法。例如::
__rich_repr__.angular = True
这会将Rich epr示例的输出更改为以下内容:
{
'gull': <Bird 'gull' eats=['fish', 'chips', 'ice cream', 'sausage rolls']>,
'penguin': <Bird 'penguin' eats=['fish'] fly=False>,
'dodo': <Bird 'dodo' eats=['fruit'] fly=False extinct=True>
}
请注意,您可以添加 __rich_repr__
方法提供给第三方库 without 将Rich作为依附者包括在内。如果没有安装Rich,那么任何东西都不会损坏。希望未来会有更多的第三方库采用Rich Repr方法。
打字¶
如果要输入Rich epr方法,可以导入并返回 rich.repr.Result
,这将有助于捕获逻辑错误::
import rich.repr
class Bird:
def __init__(self, name, eats=None, fly=True, extinct=False):
self.name = name
self.eats = list(eats) if eats else []
self.fly = fly
self.extinct = extinct
def __rich_repr__(self) -> rich.repr.Result:
yield self.name
yield "eats", self.eats
yield "fly", self.fly, True
yield "extinct", self.extinct, False
自动丰富报告¶
如果参数的名称与您的属性相同,Rich可以自动生成一个丰富的REPR。
若要自动构建富REPR,请使用 auto()
班级装饰师。上面的Bird示例遵循上述规则,因此我们不需要严格地实现我们自己的 __rich_repr__
。以下代码将生成相同的epr::
import rich.repr
@rich.repr.auto
class Bird:
def __init__(self, name, eats=None, fly=True, extinct=False):
self.name = name
self.eats = list(eats) if eats else []
self.fly = fly
self.extinct = extinct
BIRDS = {
"gull": Bird("gull", eats=["fish", "chips", "ice cream", "sausage rolls"]),
"penguin": Bird("penguin", eats=["fish"], fly=False),
"dodo": Bird("dodo", eats=["fruit"], fly=False, extinct=True)
}
from rich import print
print(BIRDS)
请注意,装饰器还将创建一个 __repr__ ,所以即使你不使用Rich打印,你也会得到一个自动生成的REPR。
如果您想要自动生成REPR的角度类型,则设置 angular=True
关于装潢::
@rich.repr.auto(angular=True)
class Bird:
def __init__(self, name, eats=None, fly=True, extinct=False):
self.name = name
self.eats = list(eats) if eats else []
self.fly = fly
self.extinct = extinct
示例¶
看见 repr.py 获取本页中使用的示例代码。