默认以十六进制打印一个 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)
这有效 -
>>> a = Hex(0xf)
>>> a += 1
>>> a
0x10
>>> a -= 1
>>> a
0xf
>>> a * 2
0x1e
我希望在打印时以十六进制格式显示一些变量、数据成员。
我目前的做法是定义一个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)
这有效 -
>>> a = Hex(0xf)
>>> a += 1
>>> a
0x10
>>> a -= 1
>>> a
0xf
>>> a * 2
0x1e