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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:18:31