是否可以在重写后恢复导入?

2024-04-27 11:36:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图编写一些代码,以防__import__被更改,因为the Pydev debugger overrides __import__。在

所以,我需要一种访问内置__import__函数的方法。在

>>> def fake_import(*args, **kwargs): pass # some other implementation here
... 
>>> import __builtin__
>>> __builtin__.__import__ = fake_import
# can I recover the original value of __import__ here?

有关于recovering removed built-ins的问题,但在本例中,全局已被替换。在


Tags: the方法函数代码importheredefargs
3条回答

查看链接的代码,原始的builtins.__import__被传递给新的ImportHookManager实例,并作为_system_import属性存储。在

因此,根据How to get instance given a method of the instance?的答案,您可以做如下操作:

__import__ = __import__.im_self._system_import

恢复原来的功能。不过,请注意,前导下划线按约定将此属性标记为私有,并且可以在不发出警告的情况下更改实现/属性名称。在

这是一个有点棘手的问题,因为python不会对重新加载__builtin__模块感兴趣,因为它没有更改。您将被迫删除__builtin__模块,以便强制python重新导入它。您也可以通过使用importlib绕过__import__(仅在python3中是这样,在python2中importlib求助于{})。在

import sys
import importlib

import __builtin__ as old_builtins

class ExampleImporter(object):
    old_import = __import__
    def __init__(self):
       self.count = 0
    def new_import(self, *args, **kwargs):
        self.count += 1
        print(args, kwargs)
        return self.old_import(*args, **kwargs)
importer = ExampleImporter()

old_builtins.__import__ = importer.new_import
assert __import__ == importer.new_import

# remove builtins from modules so as to force its reimport
del sys.modules["__builtin__"]
# in python3 the following bypasses __import__ entirely, but not in python2
new_builtins = importlib.import_module("__builtin__") 
# restore initial state of __builtin__ module (will not delete new names 
# added to __builtin__)
old_builtins.__dict__.update(new_builtins.__dict__)
# Replace new __builtin__ with old __builtin__ module. Otherwise you'll end up with a 
# mess where different modules have different a __builtin__ module.
sys.modules["__builtin__"] = old_builtins
del new_builtins

assert __import__ == importer.old_import
assert importer.count == 1 # would be 0 in python3

虽然我还没有找到恢复__import__本身的方法,但是使用ihooks我可以得到一个与{}相同的函数:

import ihooks
ihooks.ModuleImporter().install()

# or
works_just_like__import__ = ihooks.ModuleImporter().import_module

相关问题 更多 >