默认以十六进制打印一个 Python 变量

Print a Python variable in hexadecimal by default

我希望在打印时以十六进制格式显示一些变量、数据成员。

我目前的做法是定义一个class十六进制:

class Hex:
    """Facilitate printing an integer in hexadecimal format."""
    def __init__(self, data):
        if not isinstance(data, int):
            raise ValueError("Hex expects an integer.")
        self._data = data
    def __repr__(self):
        return hex(self._data)
    def __eq__(self, other):
        return self._data == other
    def __lt__(self, other):
        return self._data < other
    def __le__(self, other):
        return self._data <= other
    def __gt__(self, other):
        return self._data > other
    def __ge__(self, other):
        return self._data >= other
    def __add__(self, right):
        return self._data + right
    def __radd__(self, left):
        return self._data + left
    def __hash__(self):
        return hash(self._data)

这一切正常,如下例所示:

address = Hex(0xdeadbeef)
record1 = {'address': address, 'counter': 42}
print(record1)
{'address': 0xdeadbeef, 'counter': 42}

__hash__ 被定义为对象是可散列的并且可以用作字典中的键:

record2 = {address: 'address'}
print(record2)
{0xdeadbeef: 'address'}

定义相等和比较以便处理重复项和排序工作:

list1 = [Hex(0xff), 15, 23, Hex(0xf), 255]
print(list1)
[0xff, 15, 23, 0xf, 255]
print(set(list1))
{15, 23, 0xff}
list1.sort()
print(list1)
[15, 0xf, 23, 0xff, 255]

__add____radd__ 被定义为支持指针算法:

new_address = Hex(record1['address'] + 0x20400000)
print(new_address)
0xfeedbeef

address += 0x3f00
address += Hex(0xfe)
print(address)
0xdeadfeed

现在开始提问。

是否有一个内置的或现有的十六进制整数,它以某种方式附加了自己的 __repr__ 以十六进制打印它,否则它会作为一个整数工作。我找不到上面的 class.

上面的指针运算有效(减法,否定可以类似地添加)而且我很惊讶 += 也有效。我还应该添加 __iadd__ 吗?

我应该add/override__new__吗?像下面这样的东西不会为相同的值创建重复的实例:

def __new__(cls, *args, **kwargs):
    if not hasattr(cls, 'instances'):
        cls.instances = {}
    data = args[1]
    if data in cls.instances:
        return cls.instances[data]
    # Create if not found:
    inst = super(Hex, cls).__new__(cls) #, *args, **kwargs)
    cls.instances[data] = inst
    return inst

任何其他修复 class 十六进制或使其更好的建议?

从int继承怎么样?

>>> class Hex(int):
...  def __repr__(self):
...    return hex(self)
...
>>> a = Hex(123)
>>> a
0x7b
>>> a = Hex(16)
>>> a
0x10
>>> Hex(a + 2)
0x12

与其从头开始创建一个包含 int (_data) 的新 class,不如简单地继承 int 并覆盖 __repr__ 方法?

我不会对重复值进行优化。

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

编辑 -

通过调用 super() 和 return 作为 Hex 对象覆盖 return 新 int 的方法。例如-

def __add__(self, val):
    return Hex(super().__add__(val))

看起来有点冗长,但确实有效。另外,您可以编写一个猴子修补程序,其中包含您要覆盖的所有操作的列表 -

ops = ['__add__', '__sub__', '__mul__']

def monkey_patch(operation: str):
    """
    wraps Hex() around int's magic 
    method for provided operation.
    """
    old_op = getattr(int, operation)
    new_op = lambda self, val : Hex(old_op(self, val))
    setattr(Hex, operation, new_op)

for op in ops:
    monkey_patch(op)

full code

这有效 -

>>> a = Hex(0xf)
>>> a += 1
>>> a
0x10
>>> a -= 1
>>> a
0xf
>>> a * 2
0x1e