class FactorFloat(float):
def _factor_scale(f):
def wrapper(self, *args, **kwargs):
scaled = float.__mul__(self, FACTOR)
result = f(scaled, *args, **kwargs)
# if you want to return FactorFloats when possible:
if isinstance(result, float):
result = type(self)(result/FACTOR)
return result
return wrapper
def __repr__(self):
return '%s(%s)' % (type(self).__name__, float.__repr__(self))
__str__ = _factor_scale(float.__str__)
__mul__ = _factor_scale(float.__mul__)
__div__ = _factor_scale(float.__div__)
__add__ = _factor_scale(float.__add__)
__sub__ = _factor_scale(float.__sub__)
f = FactorFloat(3.)
FACTOR = 10.
print f # 30.0
print f-1 # 29.0
FACTOR = 2.
print f # 6.0
print f-1 # 5.0
print repr(f)
为:
30.0
29.0
6.0
5.0
FactorFloat(3.0)
编辑:
针对在评论的问题;使用类装饰器使事情变得更加通用和自动化。我不会循环使用dir(baseclass)
,而是会明确列出我希望包装的方法。在下面的例子中,我将它们列在类变量_scale_methods
中。
def wrap_scale_methods(cls):
Base = cls.__base__
def factor_scale(f):
def wrapper(self, *args, **kwargs):
scaled = Base.__mul__(self, FACTOR)
result = f(scaled, *args, **kwargs)
if isinstance(result, Base):
result = type(self)(result/FACTOR)
return result
return wrapper
for methodname in cls._scale_methods:
setattr(cls, methodname, factor_scale(getattr(Base, methodname)))
return cls
@wrap_scale_methods
class FactorComplex(complex):
_scale_methods = '__str__ __mul__ __div__ __add__ __sub__'.split()
def __repr__(self):
return '%s(%s)' % (type(self).__name__, complex.__repr__(self)[1:-1])
谢谢。只是好奇,有没有一种方法可以循环使用dir(float)而不是单独定义'__mul__','__div__'等?我问,因为我可能想尝试一个numpy数组而不是浮动。 – Paul 2010-07-10 19:30:15
请参阅编辑我的答案。 – 2010-07-10 20:45:25