为 int 覆盖 __repr__ 或 pprint

mic*_*c_e 1 python built-in python-3.x

int在调用repror 时pprint.pformat,是否有任何方法可以更改-type 对象转换为字符串的方式,以便

repr(dict(a=5, b=100))
Run Code Online (Sandbox Code Playgroud)

会给"{a: 0x5, b: 0x64}"而不是"{a: 5, b: 100}"

我想子类化int类型将是一个选项:

class IntThatPrintsAsHex(int):
    def __repr__(self):
        return hex(self)

def preprocess_for_repr(obj):
    if isinstance(obj, dict):
        return {preprocess_for_repr(k): preprocess_for_repr(v) for k, v in obj.items()}
    elif isinstance(obj, list):
        return [preprocess_for_repr(e) for e in obj]
    elif isinstance(obj, tuple):
        return tuple(preprocess_for_repr(e) for e in obj)
    elif isinstance(obj, int) and not isinstance(obj, bool):
        return IntThatPrintsAsHex(obj)
    elif isinstance(obj, set):
        return {preprocess_for_repr(e) for e in obj}
    elif isinstance(obj, frozenset):
        return frozenset(preprocess_for_repr(e) for e in obj)
    else:  # I hope I didn't forget any.
        return obj

print(repr(preprocess_for_repr(dict(a=5, b=100))))
Run Code Online (Sandbox Code Playgroud)

但是正如您所看到的,preprocess_for_repr保持“按需完成”并使用该功能是相当令人不快的。此外,明显的性能影响。

Eli*_*an9 6

int是内置类型,您不能设置内置/扩展类型的属性(您不能覆盖或向这些类型添加新方法)。但是int,您可以__repr__像这样子类化并覆盖该方法:

 class Integer(int):
     def __repr__(self):
         return hex(self)

 x = Integer(3)
 y = Integer(100)

 # prints "[0x3, 0x64]"
 print [x,y]
Run Code Online (Sandbox Code Playgroud)

Integer除了__repr__方法之外,将表现得与 int 完全一样。您可以使用它索引列表,做数学等等。但是,除非您覆盖它们,否则数学运算将返回常规int结果:

>>> print [x,y,x+1,y-2, x*y]
[0x3, 0x64, 4, 98, 300]
Run Code Online (Sandbox Code Playgroud)