只读描述符仅控制Python层实例属性访问,无法拦截对迭代器核心基类(如Iterator、PyTypeObject)的C级直接破坏;其作用限于obj.attr形式的属性读写,不涉及底层结构修改、类型对象字段篡改或解释器状态干预。

只读描述符本身不能拦截对迭代器核心基类(如 Iterator、Iterable 或 C 层的 PyTypeObject)的直接破坏。
描述符作用范围有限
描述符(包括只读描述符)仅在 Python 层控制实例属性访问,即当通过 obj.attr 读写某个被描述符管理的属性时生效。它不参与:
- 对内置类型或 C 扩展类(如
list_iterator、range_iterator)的底层结构修改; - 对类型对象(
PyTypeObject*)字段的直接内存写入(例如通过ctypes或 C 扩展篡改tp_iter、tp_iternext); - 对
builtins.iter、itertools等模块函数的行为劫持; - 对解释器运行时状态(如全局类型缓存、方法解析顺序 MRO)的篡改。
迭代器基类的“破坏”不在描述符管辖路径上
Python 的迭代器协议由两个关键方法支撑:__iter__() 和 __next__()。它们的实现通常位于:
- 用户自定义类中(此时可被描述符影响——但仅限于该类自身属性,不改变协议行为);
- 内置类型(如
list、dict)的 C 实现中(Objects/listobject.c等),完全绕过 Python 层描述符机制; -
collections.abc.Iterator这类抽象基类,仅用于isinstance检查,不参与实际调用分发。
恶意脚本若真能“直接破坏迭代器核心基类”,说明它已具备执行任意 C 级操作的能力(如通过 ctypes.CDLL 写内存、加载恶意共享库、利用解释器漏洞),此时 Python 层的任何描述符、装饰器或属性控制都早已失效。
真正可行的防护方向
面对恶意脚本,应放弃“用描述符拦截基类破坏”的错误思路,转而采用系统级与运行时策略:
-
沙箱隔离:在受限子进程(
subprocess.Popen+seccomp/ Windows Job Objects)或容器中运行不可信代码; -
导入限制:重写
__import__或使用importlib.util.spec_from_file_location配合白名单过滤危险模块(ctypes、sys、os); -
AST 静态检查:在加载前解析源码 AST,拒绝含
ctypes调用、__dict__强制赋值、type.__subclasses__枚举等高危模式的脚本; -
类型冻结加固:对关键类启用
__slots__并禁用__dict__,配合types.MappingProxyType封装类字典,降低动态篡改面。
只读描述符的合理用途
它适合保护你自己的类中那些不应被外部修改的状态字段,例如:
class SafeCounter:
def __init__(self, start=0):
self._count = start
<pre class="brush:php;toolbar:false;">@property
def count(self):
return self._count
# 无 setter → 运行时只读
这能防误用,但无法防恶意——因为攻击者可直接绕过 count 属性,改写 _count 或替换整个实例。










