如何用Rich库美化打印类实例属性中函数的源代码?
问题:使用Rich美化打印包含函数源代码的Python类
我想用rich美化打印一个包含函数列表的Python类,当前代码如下:
from dataclasses import dataclass import inspect from typing import Any, Callable from rich import print as rprint import rich.repr from rich.syntax import Syntax @dataclass class MyClass: fs: list[Callable[..., Any]] def __rich_repr__(self) -> rich.repr.Result: for f in self.fs: yield ( f.__name__, rprint( Syntax( inspect.getsource(f), lexer="python", theme="lightbulb" ), ), ) def g(x: int, y: str) -> list[str]: return [y] * x def h(y: str, zs: list[str]) -> str: return " ".join([y + z for z in zs]) my_class = MyClass([g, h]) rprint(my_class)
当前输出为:
def g(x: int, y: str) -> list[str]: return [y] * x def h(y: str, zs: list[str]) -> str: return " ".join([y + z for z in zs]) MyClass(g=None, h=None)
问题在于:函数源代码能正常打印,但类的Rich表示里属性值显示为None,因为__rich_repr__中调用的rprint会直接输出内容并返回None,而非返回可渲染的对象。我需要让类的表示中直接显示带语法高亮的函数源代码。
解决方法
修改__rich_repr__方法,直接返回Syntax实例(Rich的可渲染对象),而非调用rprint:
from dataclasses import dataclass import inspect from typing import Any, Callable from rich import print as rprint import rich.repr from rich.syntax import Syntax @dataclass class MyClass: fs: list[Callable[..., Any]] def __rich_repr__(self) -> rich.repr.Result: for f in self.fs: yield ( f.__name__, Syntax( inspect.getsource(f), lexer="python", theme="lightbulb" ), ) def g(x: int, y: str) -> list[str]: return [y] * x def h(y: str, zs: list[str]) -> str: return " ".join([y + z for z in zs]) my_class = MyClass([g, h]) rprint(my_class)
关键说明
__rich_repr__的职责是提供类的Rich渲染数据,需要返回Rich可渲染对象(如Syntax、Text等),而非直接输出内容。Syntax本身就是支持语法高亮的可渲染对象,直接将其作为属性值返回后,Rich会自动将其嵌入到类的表示中,实现带高亮的源代码展示。- 修改后,输出会将带语法高亮的函数源代码直接显示在类的属性位置,不再出现单独输出和
None的问题。
内容的提问来源于stack exchange,提问作者bzm3r
相关产品推荐
相关产品推荐

