Python受保护类封装挑战:能否在限制条件下将somevalue设为69?
Python受保护类绕过挑战
我一直疑惑是否真的无法创建Python受保护类——通常总有办法绕开封装机制,但这次我编写了一个封装完善的类,现发起挑战:在不修改1-32行代码、不使用多态的前提下,将somevalue的值设为69。
封装后的Protected类代码
from sbNative.debugtools import log # 该模块非必需,仅用于日志与调试 from inspect import stack import traceback class Protected: def __init__(self): self._somevalue = "未设置" log(self._somevalue) def __setattr__(self, name, value): # 仅允许类内部或非下划线开头的属性设置 if isinstance(stack()[1][0].f_locals.get("self"), Protected) or not name.startswith("_"): super(Protected, self).__setattr__(name, value) else: raise AttributeError("受保护类,禁止设置该属性") def __getattribute__(self, name): # 仅允许类内部或非下划线开头的属性访问 if isinstance(stack()[1][0].f_locals.get("self"), Protected) or not name.startswith("_"): return super(Protected, self).__getattribute__(name) else: raise AttributeError("受保护类,禁止访问该属性") @property def somevalue(self): return self._somevalue @somevalue.setter def somevalue(self, value): if value == 69: raise ValueError(f"{value} 是非法值。") self._somevalue = value log("实例化正常执行:") p = Protected() print("\n") log("尝试设置69失败:") try: p.somevalue = 69 except ValueError: traceback.print_exc() print("\n") log("直接访问/设置_somevalue失败:") try: p._somevalue = 69 except AttributeError: traceback.print_exc() print("") try: log(p._somevalue) except AttributeError: traceback.print_exc() print("\n") log("设置合法值420成功:") p.somevalue = 420 log(p.somevalue) print("ⁿᶦᶜᵉ ˡᶦⁿᵉ ⁿᵘᵐᵇᵉʳ ᵇᵗʷ")
绕过方案
直接调用Python所有类的基类object的原生方法,绕开子类重写的拦截逻辑:
# 直接修改受保护属性 object.__setattr__(p, '_somevalue', 69) # 验证结果 log(p.somevalue) # 输出69
原理
Protected类通过重写__setattr__和__getattribute__实现访问限制,但这些方法仅拦截通过实例直接触发的属性操作。直接调用object的__setattr__方法时,会跳过子类的拦截逻辑,直接对实例属性进行修改,从而绕过所有防护。
另一种等价实现方式:
# 获取实例的属性字典直接修改 obj_dict = object.__getattribute__(p, '__dict__') obj_dict['_somevalue'] = 69 log(p.somevalue)
内容的提问来源于stack exchange,提问作者NoBlockhit
相关产品推荐
相关产品推荐

