Skip to main content
 首页 » 编程设计

python之Python 中的继承示例

2025年05月04日14think

我不清楚如何提出这个问题。如果我这样做了,我可能会更接近解决方案。我需要对继承有一些了解。

我想创建一个float 的自定义子类型。但我希望此子类型的实例在执行任何正常的 float 方法(__add__、__mul__ 等)之前重新评估其值。在此示例中,它应将其值乘以全局因子:

class FactorFloat(float): 
    # I don't think I want to do this: 
    ##    def __new__(self, value): 
    ##        return float.__new__(self, value) 
    def __init__(self, value): 
        float.__init__(self, value) 
    # Something important is missing.. 
    # I want to do something with global FACTOR 
    # when any float method is called. 
 
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 

这只是一个经过净化的例子,我认为它能说明我的观点。如有必要,我会发布更复杂的“真实”问题。

请您参考如下方法:

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