python - 将 __builtins__ 恢复为默认值

标签 python python-3.x

如果我编码有误并且我做了这样的事情:

__builtins__ = 'abcd'

在我没有编写代码之前 import builtins 有没有办法将 __builtins__ 恢复到它的默认值?

最佳答案

让我们假设一个比所描述的情况更糟糕的情况:你完全毁掉、核武器、摧毁、歼灭和消灭 __builtins__:

__builtins__.__dict__.clear()

@Matrtijn 的方法将失败,因为每个模块都将具有完全相同的 builtins 实例。


首先,我们必须恢复基本类型:

__builtins__.object = "".__class__.__mro__[-1]
__builtins__.type = object.__class__

根据 python docs , __mro__ 属性:是在方法解析期间查找基类时考虑的类的元组。由于每个 python 现代类都扩展了 object,它允许我们获得 object 类型的实例。

其次,我们将实现类查找。给定一个类名,我们将返回类的类型。为此,我们将使用 type.__subclasses__()递归地(有关更多信息,请参阅 this question):

def all_subclasses_of(cls):
    return type.__subclasses__(cls) + [g for s in type.__subclasses__(cls) for g in all_subclasses_of(s)]
def lookup(s):
    for cls in all_subclasses_of(object):
        if cls.__name__ == s:
            return cls

第三,我们将使用 BuiltinImporter 提取已经加载的模块:

bi = lookup('BuiltinImporter')
modules = bi.load_module.__globals__['sys'].modules

我们利用 BuiltinImporter 导入 sys 模块这一事实,然后我们使用 sys.modules : 将模块名称映射到已加载模块的字典

然后,我们将使用下一步所需的方法和类修补 __builtins__:

__builtins__.hasattr = lambda obj, key: key in obj.__dict__
__builtins__.KeyError = lookup('KeyError')

现在,让奇迹发生吧!

bi.load_module('builtins')
__builtins__ = bi.load_module.__globals__['module_from_spec'](modules['builtins'].__spec__)

我们使用 builtinImporter.load_modulebuiltins 模块生成 __spec__ .然后,我们从生成的规范中加载模块。 并且有效!(我真的不知道为什么,但它确实有效)

但是,新生成的 builtins 模块缺少方法 open 和所有异常。我们必须手动添加它们才能使 import 再次工作:

__builtins__.BaseException = lookup('BaseException')
__builtins__.open = lambda name, mode: modules['io'].FileIO(name, mode)
for error in all_subclasses_of(BaseException):
    __builtins__.__dict__[error.__name__] = error

关于python - 将 __builtins__ 恢复为默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25824010/

相关文章:

python - Django - 如何在保存之前获取字段值?

python Pandas : group by several columns and count value for one column

python - 是否可以在 Python 中正确键入提示 filterM 函数?

python - 需要使用输入将 Excel 文件中同一行中的值相乘

python-3.x - 连接 Pandas 数据框中的两列

python - 使用 ctypes 时 islower 结果不正确

python - 合并两个没有键列的数据框

python - 如何修复 Windows 10 上 Python 3 中的 notification2 'dbus' 错误

python - 使用 Selenium 的 Cookie Clicker 机器人

python-3.x - 如何删除/删除 virtualenv?