Python子类继承父类@property实现类变量total_bits自动计算问题求解
问题原因
你遇到的问题核心有三点:
- 普通
@property是实例级别的装饰器,只会在类的实例上触发getter逻辑,直接通过类名访问时拿到的就是property对象本身,不会执行计算逻辑。 - 你定义的setter不符合规范,缺少接收赋值的value参数,且你的场景下
total_bits是三个属性相加的衍生值,完全不需要setter。 - 子类中冗余的
_total_bits = BitCounts.total_bits赋值属于无效代码,直接将父类的property对象赋值给了子类的类属性,没有实际作用。
修复方案
根据你的使用习惯,可以选以下任意一种方案实现,都不需要在子类编写额外计算逻辑:
方案1:使用类实例传参(全Python版本兼容)
仅需修正父类的property定义,删掉冗余代码,传参时传入类实例即可:
class BitCounts: sign_bit = 0 exponent_bits = 0 mantissa_bits = 0 @property def total_bits(self): return self.sign_bit + self.exponent_bits + self.mantissa_bits class Single(BitCounts): sign_bit = 1 offset = 0x7F exponent_bits = 8 mantissa_bits = 23 class Double(BitCounts): sign_bit = 1 offset = 0x400 exponent_bits = 11 mantissa_bits = 52 # 调用时传入类实例 def some_function(option=Single()): print("exponent bit counts are: %d" % option.exponent_bits) print("mantissa bit counts are: %d" % option.mantissa_bits) print("total bit counts are: %d" % option.total_bits)
方案2:保留直接传类的用法
如果不想实例化,自定义一个类property装饰器即可实现类级别访问:
# 自定义类property装饰器,兼容所有Python版本 class classproperty: def __init__(self, fget): self.fget = fget def __get__(self, obj, cls): return self.fget(cls) class BitCounts: sign_bit = 0 exponent_bits = 0 mantissa_bits = 0 @classproperty def total_bits(cls): return cls.sign_bit + cls.exponent_bits + cls.mantissa_bits class Single(BitCounts): sign_bit = 1 offset = 0x7F exponent_bits = 8 mantissa_bits = 23 class Double(BitCounts): sign_bit = 1 offset = 0x400 exponent_bits = 11 mantissa_bits = 52 # 用法和你原有写法完全一致,不需要修改 def some_function(option=Single): print("exponent bit counts are: %d" % option.exponent_bits) print("mantissa bit counts are: %d" % option.mantissa_bits) print("total bit counts are: %d" % option.total_bits)
如果你使用Python 3.9及以上版本,也可以直接组合@classmethod和@property代替自定义装饰器:
class BitCounts: sign_bit = 0 exponent_bits = 0 mantissa_bits = 0 @classmethod @property def total_bits(cls): return cls.sign_bit + cls.exponent_bits + cls.mantissa_bits
内容的提问来源于stack exchange,提问作者user97662
相关产品推荐
相关产品推荐

