我正在维护一个python包,在其中我进行了一些重组.现在,我想支持仍然执行from my_package.old_subpackage.foo import Foo
而不是新的from my_package.new_subpackage.foo import Foo
的客户端,而不需要显式地重新引入许多执行转发的文件.(old_subpackage
仍然存在,但不再包含foo.py
.)
我了解到有"加载器"和"查找器",我的印象是我应该为自己的目的实现loader,但到目前为止,我只实现了finder:
RENAMED_PACKAGES = {
'my_package.old_subpackage.foo': 'my_package.new_subpackage.foo',
}
# TODO: ideally, we would not just implement a "finder", but also a "loader"
# (using the importlib.util.module_for_loader decorator); this would enable us
# to get module contents that also pass identity checks
class RenamedFinder:
@classmethod
def find_spec(cls, fullname, path, target=None):
renamed = RENAMED_PACKAGES.get(fullname)
if renamed is not None:
sys.stderr.write(
f'WARNING: {fullname} was renamed to {renamed}; please adapt import accordingly!\n')
return importlib.util.find_spec(renamed)
return None
sys.meta_path.append(RenamedFinder())
然而,https://docs.python.org/3.5/library/importlib.html#importlib.util.module_for_loader和相关功能似乎被弃用.我知道这并不是我想要实现的一件很像Python 的事情,但我很高兴知道这是可以实现的.