将复杂对象打印为多行字符串



我为多个应用程序设置了非常大的设置,我想将其打印为多行字符串。让我举个例子(简化)来解释我想要实现的目标和我得到的东西。我想使用一些软件包来获得这样好的格式。

我假设构造函数的参数与__dict____slots__相同-如果不是__dict____slots__,则更重要的是显示。

我为单行写了一些格式化库,但也许多行输出和更多选项是更好的解决方案。

(重要):

请不要建议自定义__repr__或__str__ -我不能或不想自定义数百个类(特别是来自第三方库)。

class Endpoint:
def __init__(self, host_or_ip: str, port: int):
self.host_or_ip = host_or_ip
self.port = port

class ConnectionSettings:
def __init__(self, endpoints: list[Endpoint]):
self.endpoints = endpoints

class FarmSettings:
def __init__(self, name: str, connection_settings: ConnectionSettings):
self.name = name
self.connection_settings = connection_settings

def main():
settings = FarmSettings(
name='alfa',
connection_settings=ConnectionSettings(
endpoints=[
Endpoint('localhost', 80)
]
)
)
print(settings)

# what I get from default __repr__
#
# <__main__.FarmSettings object at 0x00000203EF713AF0>
#
# what do I want from some method
# FarmSettings(
#     name='alfa',
#     connection_settings=ConnectionSettings(
#         endpoints=[
#             Endpoint(name='localhost', port=80)
#         ]
#     )
# )

if __name__ == '__main__':
main()

您可以使用例如__dict__递归地将您的对象转换为字典,然后使用pprint.pprintjson.dumps来美观地打印此字典:

def dictify(obj):
if isinstance(obj, (int, float, str, bool)):
return obj
if isinstance(obj, (list, tuple)):
return list(map(dictify, obj))
return {"_type": type(obj).__name__,
**{k: dictify(v) for k, v in obj.__dict__.items()}}

settings = FarmSettings(
name='alfa',
connection_settings=ConnectionSettings(
endpoints=[
Endpoint('localhost', 80)
]
)
)
import pprint
pprint.pprint(dictify(settings))

样本输出:

{'_type': 'FarmSettings',
'connection_settings': {'_type': 'ConnectionSettings',
'endpoints': [{'_type': 'Endpoint',
'host_or_ip': 'localhost',
'port': 80}]},
'name': 'alfa'}

注意:所示的函数充其量是基本的。它不涵盖属性值的许多情况(例如dict,更不用说任何类型的更奇特的类),它也不处理你的模型中的循环引用(也就是说,在这种情况下它会陷入无尽的递归)。

在类中添加__str__(或__repr__)方法将允许您覆盖print(<insert complex object here>)的输出。例如:

def __str__(self):
return self.<attribute> + ...

例如,如果你有一个这样的类:

class Person:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
print(Person("Ryan"))

得到输出:

Ryan

最新更新