为 int 覆盖 __repr__ 或 pprint
Override __repr__ or pprint for int
在调用repr
或pprint.pformat
时,是否有任何方法可以改变int
类型对象转换为字符串的方式,例如
repr(dict(a=5, b=100))
会给出 "{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))))
但是正如您所看到的,preprocess_for_repr
函数很难保留 "as-complete-as-needed" 和使用。此外,明显的性能影响。
int
是内置类型,您不能设置 built-in/extension 类型的属性(您不能覆盖或向这些类型添加新方法)。但是,您可以继承 int
并覆盖 __repr__
方法,如下所示:
class Integer(int):
def __repr__(self):
return hex(self)
x = Integer(3)
y = Integer(100)
# prints "[0x3, 0x64]"
print [x,y]
Integer
的行为与 int 完全一样,除了 __repr__
方法。您可以使用它索引列表、做数学等等。但是,除非您覆盖它们,否则数学运算将 return 常规 int
结果:
>>> print [x,y,x+1,y-2, x*y]
[0x3, 0x64, 4, 98, 300]
您应该可以对 pprint
模块进行猴子修补,让整数以您想要的方式打印,但这并不是一个好的方法。
如果您只是为了调试寻找更好的整数表示,IPython 有自己漂亮的打印机,可以通过它的 pretty
模块轻松定制:
In [1]: from IPython.lib import pretty
In [2]: pretty.for_type(int, lambda n, p, cycle: p.text(hex(n)))
Out[2]: <function IPython.lib.pretty._repr_pprint>
In [3]: 123
Out[3]: 0x7b
In [4]: x = [12]
In [5]: x
Out[5]: [0xc]
In [6]: pretty.pretty(x)
Out[6]: '[0xc]'
您可以在链接文档中阅读有关这三个参数的更多信息。
在调用repr
或pprint.pformat
时,是否有任何方法可以改变int
类型对象转换为字符串的方式,例如
repr(dict(a=5, b=100))
会给出 "{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))))
但是正如您所看到的,preprocess_for_repr
函数很难保留 "as-complete-as-needed" 和使用。此外,明显的性能影响。
int
是内置类型,您不能设置 built-in/extension 类型的属性(您不能覆盖或向这些类型添加新方法)。但是,您可以继承 int
并覆盖 __repr__
方法,如下所示:
class Integer(int):
def __repr__(self):
return hex(self)
x = Integer(3)
y = Integer(100)
# prints "[0x3, 0x64]"
print [x,y]
Integer
的行为与 int 完全一样,除了 __repr__
方法。您可以使用它索引列表、做数学等等。但是,除非您覆盖它们,否则数学运算将 return 常规 int
结果:
>>> print [x,y,x+1,y-2, x*y]
[0x3, 0x64, 4, 98, 300]
您应该可以对 pprint
模块进行猴子修补,让整数以您想要的方式打印,但这并不是一个好的方法。
如果您只是为了调试寻找更好的整数表示,IPython 有自己漂亮的打印机,可以通过它的 pretty
模块轻松定制:
In [1]: from IPython.lib import pretty
In [2]: pretty.for_type(int, lambda n, p, cycle: p.text(hex(n)))
Out[2]: <function IPython.lib.pretty._repr_pprint>
In [3]: 123
Out[3]: 0x7b
In [4]: x = [12]
In [5]: x
Out[5]: [0xc]
In [6]: pretty.pretty(x)
Out[6]: '[0xc]'
您可以在链接文档中阅读有关这三个参数的更多信息。