我有3个python类A,B和C。A包含B对象,B包含C的对象。我想要的是当我打印一个类对象时,它应该以以下格式漂亮地打印。 C类内部也可以有更多嵌套。
A:
loc : XYZ
qual : ABC
b :
name : ABC
age : 30
c :
address : ABC
phn : 99009
下面是供参考的类。
class C(object):
def __init__(self):
self.address='ABC'
self.phn=99009
class B(object):
def __init__(self):
self.name='ABC'
self.age=30
self.c = C()
class A(object):
def __init__(self):
self.loc = 'XYZ'
self.qual = 'ABC'
self.b = B()
答案 0 :(得分:2)
以下递归函数使用__dict__
attr从头开始工作。类以获取key:value
对类的属性。从这里开始,我们只是测试该值是否为另一个类(在这种情况下,我们将再次调用我们自己),否则,我们将简单地以您期望的格式打印它。
要跟踪的唯一另一件事是当前缩进该行当前打印的级别。可以使用默认参数(indent
)轻松地完成此操作,我们可以在每次递归操作之前将其递增。
def pretty_print(clas, indent=0):
print(' ' * indent + type(clas).__name__ + ':')
indent += 4
for k,v in clas.__dict__.items():
if '__dict__' in dir(v):
pretty_print(v,indent)
else:
print(' ' * indent + k + ': ' + str(v))
它有效:
>>> pretty_print(A())
A:
loc: XYZ
qual: ABC
B:
name: ABC
age: 30
C:
address: ABC
phn: 99009
答案 1 :(得分:2)
以下方法通过让您的类从实现__str__
方法的通用基类继承而实现:
class PrettyPrinter(object):
def __str__(self):
lines = [self.__class__.__name__ + ':']
for key, val in vars(self).items():
lines += '{}: {}'.format(key, val).split('\n')
return '\n '.join(lines)
class C(PrettyPrinter):
def __init__(self):
self.address='ABC'
self.phn=99009
class B(PrettyPrinter):
def __init__(self):
self.name='ABC'
self.age=30
self.c = C()
class A(PrettyPrinter):
def __init__(self):
self.loc = 'XYZ'
self.qual = 'ABC'
self.b = B()
a = A()
print(a)
在Python 3.6及更高版本中,显示为
A:
loc: XYZ
qual: ABC
b: B:
name: ABC
age: 30
c: C:
address: ABC
phn: 99009
请注意,所有属性都会自动打印。它们的打印顺序由vars
函数确定,该函数实际上在__dict__
词典中显示。该字典在Python 3.5及更低版本中具有不确定的顺序,因此打印输出不如3.6及更高版本中的好。
答案 2 :(得分:0)
以防万一:
class C(object):
def __init__(self):
self.address='ABC'
self.phn=99009
self.my_list = [1, 2, 3, 4]
self.my_dic = {1:2, 3:4}
与print(str_pretty(C(), indent=2, key="self"))
c: (C)
address: ABC
phn: 99009
my_list: (list)
0: 1
1: 2
2: 3
3: 4
my_dic: (dict)
1: 2
3: 4
def str_pretty(obj, indent=1, rec=0, key=''):
"""Returns: pretty str of an object
obj <- the object to print
indent <- the indent per depth
rec <- used in recursion
"""
# Init
s_indent = ' ' * indent * rec
items = {}
stg = s_indent
if key != '': stg += str(key) + ': '
# Discriminate && Check if final
if isinstance(obj, list):
items = enumerate(obj)
elif isinstance(obj, dict):
items = obj.items()
elif '__dict__' in dir(obj):
items = obj.__dict__.items()
if not items:
return stg + str(obj)
# Recurse
stg += '(' + type(obj).__name__ + ')\n'
for k, v in items:
stg += str_pretty(v, indent=indent, rec=rec+1, key=k) + "\n"
# Return without empty lines
return re.sub(r'\n\s*\n', '\n', stg)[:-1]