Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 子类化int以获得十六进制表示_Python_Hex_Subclassing_Representation - Fatal编程技术网

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用于大多数字符串化对象的实例

基本上,我希望能够访问所有标准的python int运算符,例如
\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)