You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在TCL OO中让父类变量对子类只读且禁止直接访问

嘿,这个需求我刚好有成熟的解决方案!要让子类完全碰不了父类的bar属性,不管是读还是写都直接报错,咱们可以利用Python的魔法方法做属性拦截,彻底杜绝子类覆盖同名变量的问题。

完整实现代码
class Foo:
    def __init__(self):
        # 用内部变量存储实际值,避免和要保护的`bar`名称冲突
        self._bar = "父类初始值"

    def __getattribute__(self, name):
        # 拦截子类对`bar`的读取操作
        if name == "bar" and type(self) is not Foo:
            raise AttributeError("禁止访问父类的bar属性!")
        # 父类自身访问则正常返回
        return super().__getattribute__(name)

    def __setattr__(self, name, value):
        # 拦截子类对`bar`的赋值操作
        if name == "bar" and type(self) is not Foo:
            raise AttributeError("禁止修改父类的bar属性!")
        # 正常处理其他属性和父类自身的属性赋值
        super().__setattr__(name, value)

    # 父类可以通过这个方法安全访问bar的值
    def get_bar(self):
        return self._bar


class Moo(Foo):
    def __init__(self):
        super().__init__()
        # 尝试在子类里定义同名变量?不存在的,赋值直接报错
        # self.bar = "子类值"  # 取消注释会触发错误
效果测试
if __name__ == "__main__":
    # 父类实例可以正常操作
    foo = Foo()
    print("父类访问bar:", foo.get_bar())  # 输出:父类访问bar: 父类初始值
    foo._bar = "父类更新值"
    print("父类更新后bar:", foo.get_bar())  # 输出:父类更新后bar: 父类更新值

    # 子类实例访问bar直接报错
    moo = Moo()
    try:
        print(moo.bar)
    except AttributeError as e:
        print("子类读取bar报错:", e)  # 输出:子类读取bar报错: 禁止访问父类的bar属性!

    try:
        moo.bar = "子类尝试赋值"
    except AttributeError as e:
        print("子类赋值bar报错:", e)  # 输出:子类赋值bar报错: 禁止修改父类的bar属性!
原理说明
  1. 属性拦截:通过重写__getattribute__(拦截属性读取)和__setattr__(拦截属性赋值)两个魔法方法,对bar属性的访问进行检查。
  2. 实例类型判断:用type(self) is not Foo来区分当前实例是父类本身还是子类,只有子类访问bar时才触发报错。
  3. 内部变量存储:父类用_bar存储实际值,避免和对外的bar名称冲突,同时保证父类自身可以正常操作数据。
  4. 字节码层面有效:不管是直接写代码还是调用编译后的字节码,属性访问都会经过这两个魔法方法,完全杜绝子类覆盖同名变量的风险。

内容的提问来源于stack exchange,提问作者user1134991

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:28:50