You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Python自定义Sequence集合支持pprint格式化输出?

解决自定义Sequence类的pprint格式化问题

问题原因

pprint模块的格式化逻辑基于具体类型匹配,而非抽象基类。它默认仅对原生序列(list、tuple等)执行换行、缩进处理,即便你的类继承了collections.abc.Sequence,pprint也不会自动将其识别为可拆分的序列,只会直接调用__repr__输出所有内容。

解决方案1:实现__pretty__钩子(Python 3.8+)

pprint在Python 3.8及以上版本支持__pretty__方法,允许自定义对象直接复用pprint的内置格式化逻辑。修改你的MySequence类,添加该方法:

import collections
from pprint import PrettyPrinter
from dataclasses import dataclass, field
from typing import List

class MySequence(collections.abc.Sequence):
    def __init__(self, iterable):
        self.elements = list(iterable)

    def __iter__(self):
        return iter(self.elements)

    def __contains__(self, value):
        return value in self.elements

    def __getitem__(self, index):
        return self.elements.__getitem__(index)

    def __len__(self):
        return len(self.elements)

    def __repr__(self):
        return self.elements.__repr__()
    
    def __pretty__(self, printer: PrettyPrinter, cycle):
        # 复用pprint对list的格式化逻辑
        return printer._format(self.elements, cycle)

# 测试dataclass
@dataclass
class MyClass1:
    halloffame: List = field(default_factory=lambda: ["x" * 80]*4)

@dataclass
class MyClass2:
    halloffame: MySequence = field(default_factory=lambda: MySequence(["x" * 80]*4))

# 验证输出
from pprint import pprint
pprint(MyClass1())
pprint(MyClass2())

解决方案2:注册自定义格式化器(兼容旧Python版本)

如果使用Python 3.7及以下版本,可通过注册自定义格式化函数到pprint的分发器,让pprint按list的规则处理MySequence:

import collections
from pprint import PrettyPrinter
from dataclasses import dataclass, field
from typing import List

class MySequence(collections.abc.Sequence):
    # 保持原有实现不变
    def __init__(self, iterable):
        self.elements = list(iterable)
    def __iter__(self):
        return iter(self.elements)
    def __contains__(self, value):
        return value in self.elements
    def __getitem__(self, index):
        return self.elements.__getitem__(index)
    def __len__(self):
        return len(self.elements)
    def __repr__(self):
        return self.elements.__repr__()

# 注册MySequence的格式化函数
def format_mysequence(obj, stream, indent, allowance, context, level):
    PrettyPrinter._format_list(obj.elements, stream, indent, allowance, context, level)

PrettyPrinter._dispatch[MySequence] = format_mysequence

# 测试dataclass
@dataclass
class MyClass1:
    halloffame: List = field(default_factory=lambda: ["x" * 80]*4)

@dataclass
class MyClass2:
    halloffame: MySequence = field(default_factory=lambda: MySequence(["x" * 80]*4))

# 验证输出
from pprint import pprint
pprint(MyClass1())
pprint(MyClass2())

验证效果

两种方案都会让MyClass2的pprint输出与MyClass1完全一致:

MyClass1(halloffame=['xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                     'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                     'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                     'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'])
MyClass2(halloffame=['xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                     'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                     'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                     'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'])

内容的提问来源于stack exchange,提问作者BorjaEst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 02:31:14