2

基本上我想访问所有标准的python int 运算符,例如__and____xor__,特别是当最终打印结果时,我希望它以十六进制格式表示。(有点像将我的计算器置于十六进制模式)

class Hex(int):
  def __repr__(self):
    return "0x%x"%self
  __str__=__repr__ # this certainly helps with printing

if __name__=="__main__":
  print Hex(0x1abe11ed) ^ Hex(440720179)
  print Hex(Hex(0x1abe11ed) ^ Hex(440720179))

理想情况下,输出的两行都应该是十六进制:0xfacade,但是第一行产生十进制:16435934

有任何想法吗?

4

5 回答 5

7

您应该分别定义__repr____str__

class Hex(int):
  def __repr__(self):
    return "Hex(0x%x)" % self
  def __str__(self):
    return "0x%x" % self

__repr__函数应该(如果可能)提供可eval()用于重建原始对象的 Python 文本。另一方面,__str__可以只返回对象的人类可读表示。

于 2009-08-07T02:49:45.360 回答
6

装饰器,尤其是在 Python 2.6 及更高版本中,是包装许多方法以“返回此类类型的实例而不是超类的实例”的最便捷方式,正如其他人所指出的那样,这是您的潜在问题(除了__str__对 vs的吹毛求疵之外__repr__,值得但对您的问题根本没有解决办法;-)。

def returnthisclassfrom(specials):
  specialnames = ['__%s__' % s for s in specials.split()]
  def wrapit(cls, method):
    return lambda *a: cls(method(*a))
  def dowrap(cls):
    for n in specialnames:
      method = getattr(cls, n)
      setattr(cls, n, wrapit(cls, method))
    return cls
  return dowrap

@returnthisclassfrom('and or xor')
class Hex(int):
  def __repr__(self): return hex(self)
  __str__ = __repr__

a = Hex(2345)
b = Hex(5432)
print a, b, a^b

在 Python 2.6 中,这会发出

0x929 0x1538 0x1c11

如预期的。当然你可以给装饰器添加更多的方法名等等;如果您坚持使用 Python 2.5,请删除装饰线(以 开头的那条@)并改用

class Hex(int):
  def __repr__(self): return hex(self)
  __str__ = __repr__
Hex = returnthisclassfrom('and or xor')(Hex)

有点不那么优雅,但同样有效;-)

编辑:修复了代码中“通常的范围问题”的发生。

于 2009-08-07T05:35:09.923 回答
1

您需要让运算符(+、-、** 等)返回 Hex 实例。照原样,它将返回整数,即

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

我不知道这个,我觉得必须有更好的方法,而不必重写每个运算符以返回Hex???

于 2009-08-07T03:21:11.067 回答
1

回应您的评论:

你可以自己写一个 Mixin:

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__ 
于 2009-08-07T04:05:38.763 回答
0

也覆盖__str__

__repr__在调用 repr(o) 时使用,并在交互式提示中显示一个值。 __str__在大多数字符串化对象的实例中调用,包括在打印对象时。

对象的默认__str__行为是回退到repr,但int提供了自己的__str__方法(与__repr__(在 Python 3 之前)相同,但不回退到__repr__

于 2009-08-07T02:29:09.340 回答