用 Rich 打印 dict()

问题描述

我正在尝试使用 Pythons Rich 打印 dict()。根据我的理解,这应该在不同的行等上输出数据。有点像 pprint

但我得到:

>>> from rich import print
>>> print(output)

{'GigabitEthernet0/1': {'description': '## Connected to leaf-2 ##','type': 'iGbE','oper_status': 'up','phys_address': '5000.0009.0001','port_speed': 'auto speed','mtu': 1500,'enabled': True,'bandwidth': 1000000,'flow_control': {'receive': False,'send': False},'mac_address': '5000.0009.0001','auto_negotiate': True,'port_channel': {'port_channel_member': False},'duplex_mode': 'auto','delay': 10,'accounting': {'other': {'pkts_in':
0,'chars_in': 0,'pkts_out': 431258,'chars_out': 25875480},'ip': {'pkts_in': 513383,'chars_in': 42910746,'pkts_out': 471188,'chars_out': 45342027},'dec mop': {'pkts_in': 0,'pkts_out': 7163,'chars_out': 
551551},'arp': {'pkts_in': 3845,'chars_in': 230700,'pkts_out': 3846,'chars_out': 230760},'cdp': {'pkts_in': 72010,'chars_in': 18866620,'pkts_out': 79879,'chars_out': 31221768}},'ipv4': {'10.1.1.5/30': {'ip': '10.1.1.5',...

有什么建议吗?

解决方法

TL;DR 如果您的字典不是dict,请进行显式转换。


从您的词典的内容来看,我假设您的 output 来自 Cisco IOS 等网络设备配置,我对这些领域很不了解,无法弄清楚您在哪里获取您的数据。

您用来获取 output 的模块或脚本可能实际上返回了一个名为 MappingProxyTypedict 类型。

我推测这就是为什么你的文字有颜色但没有美化。


例如让我们看看 rich.printstr.__dict__ 做了什么:

>>> from rich import print
>>> print(str.__dict__)

这看起来像这样,就像你的一样。

enter image description here

请注意,这是在 WSL2 中运行的 xfce4 终端,被吸引到 X410 X 服务器。一个功能齐全的终端。

这确实看起来像普通 dict,但让我们看看它到底是什么:

>>> type(str.__dict__)
<class 'mappingproxy'>

>>> from types import MappingProxyType
>>> isinstance(str.__dict__,MappingProxyType)
True

>>> isinstance(str.__dict__,dict)
False

如你所见,尽管它的输出看起来像一本字典,但它不是。

types.MappingProxyType 本质上是一个只读字典,不一定是 dict。像 rich 这样的 3rd 方库的开发者可能已经忘记了这种类型的存在。如果是这种情况,那么 rich.print 会做内置的 print() 会做的事情:调用 __repr__/__str__ - 现在只是将其视为字符串。

我们可以通过传递看起来像方法的 __repr__string 来确认这种行为,并且仍然得到富文本处理。

enter image description here

还可以通过自己创建 MappingProxyType 的实例。

>>> from types import MappingProxyType
>>> from rich import print

>>> data = {f"{n}": n for n in range(11)}

>>> print(data)
{
    '0': 0,'1': 1,'2': 2,'3': 3,'4': 4,'5': 5,'6': 6,'7': 7,'8': 8,'9': 9,'10': 10
}

>>> print(MappingProxyType(data))
{'0': 0,'10': 10}

从中您可以看到类型如何影响 rich.print 的输出。

要修复,只需将 types.MappingProxyType 转换为 dict

>>> from rich import print
>>> print(dict(str.__dict__))

enter image description here

这比以前更漂亮 - 排除 __doc__ 值,它是单个字符串,无法帮助。