Python开发解释器时如何存储可执行文本而非仅作为str处理
实现方案
完全可以实现,不需要什么特殊黑科技,Python原生能力就能覆盖你的需求,核心逻辑是始终以原始字符串形式存储代码内容,需要执行时再动态调度,不要提前把内容转成不可编辑的执行对象。
基础实现(无额外封装)
你不需要给字符串套任何自定义类型,普通str就完全满足要求:
- 存储时直接把代码文本赋值给字符串变量,所有字符串的编辑操作(切片、替换、正则匹配、拼接)都可以正常使用
- 需要打印时直接传进
print()就能输出原始代码文本 - 需要执行时用
exec()传入自定义作用域运行即可,和你的自定义解释器逻辑完全适配
示例代码:
# 先定义你自定义解释器里的内置out方法 def out(content): print(f"[解释器输出] {content}") # 存储代码文本,和你给的示例完全一致 code = "out('text')" # 可自由做字符串编辑操作 code = code.replace("text", "修改后的内容") + "\nout('第二行输出')" # 直接打印就能看到原始代码 print("当前存储的代码:\n", code) # 执行代码,传入自定义命名空间,不会污染全局环境 custom_namespace = {"out": out} exec(code, custom_namespace)
带扩展属性的实现
如果你需要给存储的代码附加额外信息(比如来源文件、行号、语法标记),用dataclass简单封装一层就行,实现__str__方法之后就可以直接被print调用,和普通字符串使用体验一致:
from dataclasses import dataclass @dataclass class StoredCode: raw_text: str source_file: str line_no: int def __str__(self): # print实例时直接返回原始代码文本 return self.raw_text def exec(self, custom_ns=None): if custom_ns is None: custom_ns = {} exec(self.raw_text, custom_ns) # 用法 snippet = StoredCode( raw_text="out('text')", source_file="test.my", line_no=3 ) # 直接print和普通字符串无区别 print(snippet) # 编辑内容直接修改raw_text属性即可 snippet.raw_text = snippet.raw_text.replace("text", "新内容") # 执行代码 snippet.exec({"out": out})
注意事项
- 不要一开始就用
compile()把代码预编译成代码对象存储,编译后的对象无法再做文本编辑;除非你有极高的性能要求,可以加一层缓存:每次raw_text修改后清空缓存,执行时如果缓存为空就重新编译,否则直接用缓存的代码对象执行。
安全提示:如果你的解释器会运行外部不可信来源的代码,不要直接使用裸
exec,需要自行做语法校验、沙箱隔离,避免恶意代码执行带来的风险。
内容的提问来源于stack exchange,提问作者fezki
相关产品推荐
相关产品推荐

