Python 子类化int以获得十六进制表示
基本上,我希望能够访问所有标准的python int运算符,例如Python 子类化int以获得十六进制表示,python,hex,subclassing,representation,Python,Hex,Subclassing,Representation,基本上,我希望能够访问所有标准的python int运算符,例如\uuuu和\uuuuu和\uuuuuuuuxor\uuuu等,特别是在最终打印结果时,我希望它以十六进制格式表示。(有点像将计算器置于十六进制模式) 理想情况下,两行输出都应该是十六进制:0xfacade,但是第一行输出的是十进制:16435934 有什么想法吗?也要重写\uuuuuuuuuuuuu 调用repr(o)时使用\uuuu repr\uuu,并在交互提示下显示值\uuuu str\uuuuu用于大多数字符串化对象的实例
\uuuu和\uuuuu
和\uuuuuuuuxor\uuuu
等,特别是在最终打印结果时,我希望它以十六进制格式表示。(有点像将计算器置于十六进制模式)
理想情况下,两行输出都应该是十六进制:0xfacade,但是第一行输出的是十进制:16435934
有什么想法吗?也要重写\uuuuuuuuuuuuu
调用repr(o)时使用\uuuu repr\uuu
,并在交互提示下显示值<代码>\uuuu str\uuuuu
用于大多数字符串化对象的实例,包括打印对象时
对象的默认
\uuuuu str\uuuuu
行为是返回到repr
,但是int
提供了自己的\uuuuu str\uuuu
方法(与\uuuuu repr\uuuuu
相同,但不返回到\uuuuuuuuuu repr\uuu
).您应该分别定义\uuuu repr\uuuu
和\uu str\uuuu
:
class Hex(int):
def __repr__(self):
return "Hex(0x%x)" % self
def __str__(self):
return "0x%x" % self
\uuuu repr\uuuu
函数应该(如果可能的话)提供Python文本,可以对其进行eval()
评估以重建原始对象。另一方面,\uuu str\uuu
只能返回对象的可读表示。您需要让运算符(+、-、**等)返回十六进制的实例。按原样,它将返回int,即
class Hex(int):
def __repr__(self):
return "Hex(0x%x)" % self
def __str__(self):
return "0x%x" % self
>>> h1 = Hex(100)
>>> h2 = Hex(1000)
>>> h1
Hex(0x64)
>>> h2
Hex(0x3e8)
>>> h1+h2
1100
>>> type(h1+h2)
<type 'int'>
class十六进制(int):
定义报告(自我):
返回“十六进制(0x%x)”%self
定义(自我):
返回“0x%x”%self
>>>h1=十六进制(100)
>>>h2=十六进制(1000)
>>>h1
十六进制(0x64)
>>>氢
十六进制(0x3e8)
>>>h1+h2
1100
>>>类型(h1+h2)
因此,您可以覆盖各种运算符:
class Hex(int):
def __repr__(self):
return "Hex(0x%x)" % self
def __str__(self):
return "0x%x" % self
def __add__(self, other):
return Hex(super(Hex, self).__add__(other))
def __sub__(self, other):
return self.__add__(-other)
def __pow__(self, power):
return Hex(super(Hex, self).__pow__(power))
def __xor__(self, other):
return Hex(super(Hex, self).__xor__(other))
>>> h1 = Hex(100)
>>> h2 = Hex(1000)
>>> h1+h2
Hex(0x44c)
>>> type(h1+h2)
<class '__main__.Hex'>
>>> h1 += h2
>>> h1
Hex(0x44c)
>>> h2 ** 2
Hex(0xf4240)
>>> Hex(0x1abe11ed) ^ Hex(440720179)
>>> Hex(0xfacade)
class十六进制(int):
定义报告(自我):
返回“十六进制(0x%x)”%self
定义(自我):
返回“0x%x”%self
定义添加(自身、其他):
返回十六进制(超级(十六进制,自).\uuuu添加(其他))
定义(自身、其他):
返回自我。添加(其他)
定义功率(自身、电源):
返回十六进制(超级(十六进制,自我)。\uuuuu功率(功率))
定义异或(自身、其他):
返回十六进制(超级(十六进制,自身)。\uuuuxor\uuuuuuuuxor(其他))
>>>h1=十六进制(100)
>>>h2=十六进制(1000)
>>>h1+h2
十六进制(0x44c)
>>>类型(h1+h2)
>>>h1+=h2
>>>h1
十六进制(0x44c)
>>>h2**2
十六进制(0xf4240)
>>>十六进制(0x1abe11ed)^Hex(440720179)
>>>十六进制(0xfacade)
我不知道这一点,我觉得必须有一种更好的方法,不必重写每个操作符,就可以返回
Hex的实例来回应您的评论:
你可以自己写一个混音:
class IntMathMixin:
def __add__(self, other):
return type(self)(int(self).__add__(int(other)))
# ... analog for the others
然后像这样使用它:
class Hex(IntMathMixin, int):
def __repr__(self):
return "0x%x"%self
__str__=__repr__
类装饰器,特别是在Python2.6及更高版本中,是包装许多方法以“返回该类类型的实例而不是超类的实例”的最方便的方法,正如其他人所指出的,这是您的根本问题(除了与\uuuu str\uuuuuu
和\uuuu repr\uuuuuuu
之间的争论之外,对你的问题来说是值得的,但根本没有解决的办法;-)
在Python2.6中,这会发出
0x929 0x1538 0x1c11
当然,您可以向decorator添加更多的方法名,等等;如果您仍然使用Python 2.5,请删除装饰行(以@
开头的那一行)并使用
class Hex(int):
def __repr__(self): return hex(self)
__str__ = __repr__
Hex = returnthisclassfrom('and or xor')(Hex)
不那么优雅,但同样有效;-)
编辑:修复了代码中出现的“常规作用域问题”。为什么不使用内置函数hex()
?在多个适当的位置插入hex(),既耗时又不精确。切换Hex(int)类型的任何表示形式都将是一个简单的重构。然而:我认为需要重载所有十六进制/整数并元运算符来返回十六进制结果(目前它们仍然产生整数)。可能有一个“Mixin”用于批量重载运算符。为注意到str和repr之间的区别而欢呼。由于repr(23)和str(23)给出完全相同的结果字符串,我不会特别热,也不会为int的子类也这样做而烦恼——毕竟如果Hex在模块中,你永远不知道是否返回‘Hex(0x0)’'或'themodule.Hex(0x0)'(因为您不知道导入是如何表达的!),所以字符串的eval
-能力是非常不确定的(\uuuu import\uuuu('themodule').Hex(0x0)
对于不在子包中的模块来说是更广泛的可评估的,但是如果我在代码审查中看到了从<代码>返回到RePrpg< <代码>,我将否决提交变更集!-)。显然,它不可能在所有情况下都做正确的事情。“最佳”努力(为了最有可能评估)将是上面带有\uuuuuu import\uuuuu
的字符串,我只是不想看到这一点,所以“不太好”更好。由于容器的\uuuu str\uuuu
在项目上使用了\uuuu repr\uuuu
,我倾向于不强调区别。我知道一定有更简单的解决办法。但我不知道有人可以在类中使用装饰器。谢谢。@Ralph,不客气!自python 2.6以来,只支持decorator语法,但我还展示了如何在较旧的python中的类上使用decorator(语法不太优雅)(例如,2.5,您被困在google app engine中,或者系统为python提供MacOSX和许多Linux发行版等;-)。这有问题(至少在Python 2.5上)如果specials中的最后一个方法名称也用于所有前面的方法,例如,打印a、b、a&b、a | b、a^b>>0x929 0x1538 0x1c11 0x1c11 0x1c11
,但它应该是0x929 0x1538 0x128 0x1d39 0x1c11
。是的,问题在于lambda在执行时使用方法的最后一个绑定值,因此它将始终使用最后一个方法在特价商品列表中的od。为什么\uuuuu str\uuuu=\uuuu repr\uuuuu
?我猜int
的\uuu str\uuuuu
没有根据对象隐式地落入\uuuuu repr\uuu
中。有什么原因吗
0x929 0x1538 0x1c11
class Hex(int):
def __repr__(self): return hex(self)
__str__ = __repr__
Hex = returnthisclassfrom('and or xor')(Hex)