Когда пользователь говорит
print(the_object.the_dict['level1']['level2']['level3'])
Python оценивает the_object.the_dict['level1']['level2']['level3']
и (скажем) находит, что это диктат, и передает его на print
.
Так как the_object.the_dict
является диктатом, остальное находится вне контроля the_object
. Когда вы пройдете через level1
, level2
и level3
, только тип объекта, возвращаемый the_object.the_dict['level1']['level2']['level3']
, будет влиять на поведение print
. Метод the_object
__str__
не повлияет ни на что, кроме the_object
.
Более того, при печати вложенных объектов pprint.pformat
использует repr
объекта, а не str
объекта.
Итак, чтобы получить поведение, которое мы хотим, нам нужно the_object.the_dict['level1']['level2']['level3']
, чтобы оценить что-то вроде диктата, но с другим __repr__
...
Вы можете сделать объект, похожий на диктовку (например, Turtle
) и использовать Turtles
до упора:
import collections
import pprint
class Turtle(collections.MutableMapping):
def __init__(self,*args,**kwargs):
self._data=dict(*args,**kwargs)
def __getitem__(self,key):
return self._data[key]
def __setitem__(self, key, value):
self._data[key]=value
def __delitem__(self, key):
del self._data[key]
def __iter__(self):
return iter(self._data)
def __len__(self):
return len(self._data)
def __contains__(self, x):
return x in self._data
def __repr__(self):
return pprint.pformat(self._data)
class MyObject(object):
def __init__(self):
self.the_dict=Turtle()
def __repr__(self):
return repr(self.the_dict)
the_object=MyObject()
the_object.the_dict['level1']=Turtle()
the_object.the_dict['level1']['level2']=Turtle()
the_object.the_dict['level1']['level2']['level3']=Turtle({i:i for i in range(20)})
print(the_object)
print(the_object.the_dict['level1']['level2']['level3'])
Чтобы использовать это, вы должны заменить все диктанты в вашей структуре вложенных диктов на Turtle
s.
Но на самом деле (как вы можете судить по моим причудливым именам), я не ожидаю, что вы будете использовать Turtle
s. Dicts - это такие хорошие, оптимизированные встроенные функции, я бы не хотел добавлять этот промежуточный объект просто для того, чтобы добиться красивой печати.
Если вместо этого вы сможете убедить своих пользователей набрать
from pprint import pprint
тогда они могут просто использовать
pprint(the_object.the_dict['level1']['level2']['level3'])
чтобы получить красивую печать.