Python从另一个文件导出的包的子模块导入
我已经imports.py包含:
import os as exported_os
并foo.py包含:
from imports import exported_os
print(exported_os.path.devnull) # works
from imports.exported_os.path import devnull # doesn't
有没有办法让第二次导入工作?我尝试添加__path__到imports.py与它摆弄,但不能得到任何东西。
实际用例:os是some_library_version_n和exported_os是some_library_version(我试图避免some_library_version_n在不同文件中拥有多个实例)。
回答
一种方法
目录结构:
__init__.py
foo.py
imports/
? __init__.py
? exported_os/
? __init__.py
? path.py
imports/exported_os/__init__.py:
from . import path
from os import * # not necessary for the question
# but it makes `exported_os` more like `os`
# e.g., `exported_os.listdir` will be callable
imports/exported_os/path.py:
from os.path import *
通过这种方式,您可以exported_os像使用ossubmodule一样使用它path。与 不同import,from需要模块和类。
另一种方法
imports.py:
import os
import sys
ms = []
for m in sys.modules:
if m.startswith('os'):
ms.append(m)
for m in ms:
sys.modules['imports.exported_os' + m[2:]] = sys.modules[m]
或者,通过显式扩展,sys.modules您可以exported_os像os使用它的子模块一样使用。
为什么您不能简单地更改名称 os
如果打开,.../lib/python3.9/os.py您可以找到以下行:
sys.modules['os.path'] = path
因此,即使您复制.../lib/python3.9/os.py到.../lib/python3.9/exported_os.py,以下内容也不起作用:
from exported_os.path import devnull
但是,如果您将线路更改sys.modules['os.path']为sys.modules['exported_os.path']它的工作原理。