基本上我想要访问所有标准的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
有什么想法吗?
答案 0 :(得分: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__
只能返回对象的人类可读表示。
答案 1 :(得分: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)
螨虫不那么优雅,但同样有效; - )
修改:修复了代码中“通常的范围问题”的出现。
答案 2 :(得分: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
???的实例
答案 3 :(得分: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__
答案 4 :(得分:0)
也覆盖__str__
。
__repr__
,并在交互式提示符下显示值。大多数字符串化对象的实例都会调用__str__
,包括何时打印它。
对象的默认__str__
行为是回退到repr
,但int
提供了自己的__str__
方法(与{{1}相同) (在Python 3之前),但不回退到__repr__
)。