จากสิ่งที่ได้ทำไปแล้วฉันไม่เห็นเครื่องพิมพ์สวย ๆ ที่อย่างน้อยเลียนแบบเอาท์พุทของหลามล่ามด้วยการจัดรูปแบบที่ง่ายมากดังนั้นนี่คือของฉัน:
class Formatter(object):
def __init__(self):
self.types = {}
self.htchar = '\t'
self.lfchar = '\n'
self.indent = 0
self.set_formater(object, self.__class__.format_object)
self.set_formater(dict, self.__class__.format_dict)
self.set_formater(list, self.__class__.format_list)
self.set_formater(tuple, self.__class__.format_tuple)
def set_formater(self, obj, callback):
self.types[obj] = callback
def __call__(self, value, **args):
for key in args:
setattr(self, key, args[key])
formater = self.types[type(value) if type(value) in self.types else object]
return formater(self, value, self.indent)
def format_object(self, value, indent):
return repr(value)
def format_dict(self, value, indent):
items = [
self.lfchar + self.htchar * (indent + 1) + repr(key) + ': ' +
(self.types[type(value[key]) if type(value[key]) in self.types else object])(self, value[key], indent + 1)
for key in value
]
return '{%s}' % (','.join(items) + self.lfchar + self.htchar * indent)
def format_list(self, value, indent):
items = [
self.lfchar + self.htchar * (indent + 1) + (self.types[type(item) if type(item) in self.types else object])(self, item, indent + 1)
for item in value
]
return '[%s]' % (','.join(items) + self.lfchar + self.htchar * indent)
def format_tuple(self, value, indent):
items = [
self.lfchar + self.htchar * (indent + 1) + (self.types[type(item) if type(item) in self.types else object])(self, item, indent + 1)
for item in value
]
return '(%s)' % (','.join(items) + self.lfchar + self.htchar * indent)
ในการเริ่มต้น:
pretty = Formatter()
มันสามารถรองรับการเพิ่มตัวจัดรูปแบบสำหรับชนิดที่กำหนดคุณเพียงแค่ต้องสร้างฟังก์ชันสำหรับสิ่งนี้และผูกกับประเภทที่คุณต้องการด้วย set_formater:
from collections import OrderedDict
def format_ordereddict(self, value, indent):
items = [
self.lfchar + self.htchar * (indent + 1) +
"(" + repr(key) + ', ' + (self.types[
type(value[key]) if type(value[key]) in self.types else object
])(self, value[key], indent + 1) + ")"
for key in value
]
return 'OrderedDict([%s])' % (','.join(items) +
self.lfchar + self.htchar * indent)
pretty.set_formater(OrderedDict, format_ordereddict)
ด้วยเหตุผลทางประวัติศาสตร์ฉันเก็บเครื่องพิมพ์สวยไว้ก่อนหน้านี้ซึ่งเป็นฟังก์ชั่นแทนที่จะเป็นคลาส แต่พวกเขาทั้งสองสามารถใช้วิธีเดียวกันรุ่นคลาสก็อนุญาตได้มากขึ้น:
def pretty(value, htchar='\t', lfchar='\n', indent=0):
nlch = lfchar + htchar * (indent + 1)
if type(value) is dict:
items = [
nlch + repr(key) + ': ' + pretty(value[key], htchar, lfchar, indent + 1)
for key in value
]
return '{%s}' % (','.join(items) + lfchar + htchar * indent)
elif type(value) is list:
items = [
nlch + pretty(item, htchar, lfchar, indent + 1)
for item in value
]
return '[%s]' % (','.join(items) + lfchar + htchar * indent)
elif type(value) is tuple:
items = [
nlch + pretty(item, htchar, lfchar, indent + 1)
for item in value
]
return '(%s)' % (','.join(items) + lfchar + htchar * indent)
else:
return repr(value)
วิธีใช้:
>>> a = {'list':['a','b',1,2],'dict':{'a':1,2:'b'},'tuple':('a','b',1,2),'function':pretty,'unicode':u'\xa7',("tuple","key"):"valid"}
>>> a
{'function': <function pretty at 0x7fdf555809b0>, 'tuple': ('a', 'b', 1, 2), 'list': ['a', 'b', 1, 2], 'dict': {'a': 1, 2: 'b'}, 'unicode': u'\xa7', ('tuple', 'key'): 'valid'}
>>> print(pretty(a))
{
'function': <function pretty at 0x7fdf555809b0>,
'tuple': (
'a',
'b',
1,
2
),
'list': [
'a',
'b',
1,
2
],
'dict': {
'a': 1,
2: 'b'
},
'unicode': u'\xa7',
('tuple', 'key'): 'valid'
}
เปรียบเทียบกับรุ่นอื่น:
- โซลูชันนี้จะค้นหาประเภทวัตถุโดยตรงดังนั้นคุณสามารถพิมพ์ได้เกือบทุกอย่างไม่เพียง แต่รายการหรือ dict
- ไม่มีการพึ่งพาใด ๆ
- ทุกอย่างถูกใส่ไว้ในสตริงดังนั้นคุณสามารถทำสิ่งที่คุณต้องการได้
- คลาสและฟังก์ชันได้รับการทดสอบและใช้งานได้กับ Python 2.7 และ 3.4
- คุณสามารถมีวัตถุทุกชนิดที่อยู่ภายในนี่คือการแสดงของพวกเขาและไม่ใช่เนื้อหาของพวกเขาที่ถูกวางในผลลัพธ์ (ดังนั้นสตริงมีคำพูดสตริง Unicode จะถูกแสดงอย่างเต็มที่ ... )
- ด้วยเวอร์ชันคลาสคุณสามารถเพิ่มการจัดรูปแบบสำหรับวัตถุทุกประเภทที่คุณต้องการหรือเปลี่ยนเป็นประเภทที่กำหนดไว้แล้ว
- คีย์สามารถเป็นประเภทที่ถูกต้องใด ๆ
- สามารถเปลี่ยนเยื้องและอักขระขึ้นบรรทัดใหม่สำหรับทุกสิ่งที่เราต้องการ
- Dict, List และ Tuples นั้นถูกพิมพ์ออกมาสวย