我为多个应用程序设置了非常大的设置,我想将其打印为多行字符串。让我举个例子(简化)来解释我想要实现的目标和我得到的东西。我想使用一些软件包来获得这样好的格式。
我假设构造函数的参数与__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.pprint
或json.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