You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 23:01:00