Override __repr__ or pprint for int

笑着哭i 提交于 2019-12-24 08:30:15

问题


Is there any way of changing the way a int-type object is converted to string when calling repr or pprint.pformat, such that

repr(dict(a=5, b=100))

will give "{a: 0x5, b: 0x64}" instead of "{a: 5, b: 100}"?

I suppose subclassing the int type would be an option:

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))))

But as you can see, the preprocess_for_repr function is rather unpleasant to keep "as-complete-as-needed" and to work with. Also, the obvious performance implications.


回答1:


You should be able to monkey patch the pprint module to have integers print the way you want, but this isn't really a good approach.

If you're just looking for a better representation of integers for debugging, IPython has its own pretty printer that is easily customizable through its pretty module:

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]'

You can read more about the three parameters in the linked documentation.




回答2:


int is a builtin type and you can't set attributes of built-in/extension types (you can not override nor add new methods to these types). You could however subclass int and override the __repr__ method like this:

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

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

 # prints "[0x3, 0x64]"
 print [x,y]

Integer will behave exactly like an int, except for the __repr__ method. You can use it index lists, do math and so on. However unless you override them, math operations will return regular int results:

>>> print [x,y,x+1,y-2, x*y]
[0x3, 0x64, 4, 98, 300]


来源:https://stackoverflow.com/questions/39095294/override-repr-or-pprint-for-int

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!