Python继承类变量赋值异常:如何让子类调用父类变量时使用子类值?
解决Python类变量继承时的初始化时机问题
这个问题我太熟啦!你遇到的是Python类变量初始化时机的坑——基类里的var1和var2在类定义阶段就已经计算好了,那时候CLASS_CODE还是None,所以子类继承过来的是已经生成好的'ENone001',而不是用子类的CLASS_CODE重新计算的结果。
下面给你两种实用的解决方案,按需选择:
方案一:用类级别的@property动态计算
适合需要动态获取最新CLASS_CODE的场景,每次访问属性时都会重新计算:
class Base(object): CLASS_CODE = None # 子类必须设置这个值 @classmethod @property def var1(cls): return f'E{cls.CLASS_CODE}001' @classmethod @property def var2(cls): return f'E{cls.CLASS_CODE}002' class Child(Base): CLASS_CODE = 'Child'
现在调用Child.var1就会返回'EChild001'啦!原理是把var1和var2变成类属性的getter方法,每次访问时都会用当前子类的CLASS_CODE生成字符串,彻底避开初始化时机的问题。
方案二:用元类静态生成类变量
如果希望var1和var2是静态的类变量(不需要每次访问都计算),可以用元类在子类创建时自动生成这些变量:
class BaseMeta(type): def __new__(cls, name, bases, attrs): # 当子类定义了CLASS_CODE时,自动生成对应的var1和var2 if 'CLASS_CODE' in attrs and attrs['CLASS_CODE'] is not None: attrs['var1'] = f'E{attrs["CLASS_CODE"]}001' attrs['var2'] = f'E{attrs["CLASS_CODE"]}002' return super().__new__(cls, name, bases, attrs) class Base(object, metaclass=BaseMeta): CLASS_CODE = None class Child(Base): CLASS_CODE = 'Child'
元类的__new__方法会在类创建的那一刻被触发,这时候我们可以检测子类的CLASS_CODE,直接生成对应的静态变量,既满足需求又不影响访问效率。
不推荐的方案(重复代码多)
当然你也可以在子类里显式重新定义var1和var2,但这种方法会产生大量重复代码,维护起来很麻烦,除非你的子类数量极少,否则不建议用:
class Base(object): CLASS_CODE = None class Child(Base): CLASS_CODE = 'Child' var1 = f'E{CLASS_CODE}001' var2 = f'E{CLASS_CODE}002'
内容的提问来源于stack exchange,提问作者Praful Bagai
相关产品推荐
相关产品推荐

