导入时将 Python 模块重新路由到另一个目录(子版本)
Reroute Python Module To Another Directory (Sub-version) on import
mypkg/
├── mypkg-1_0_0/
│ ├── __init__.py
├── __init__.py
以上目录是我的模块目录的示例。主模块 mypkg
包含所有子版本。当我执行 import mypkg
时,__init__
文件旨在将导入重定向到正确的版本,而 运行 目标版本 __init__
文件并将属性设置为 globals()
这是 mypkg
中的 __init__.py
的样子:
def __load():
import os
pkgrelease = "mypkg-1_0_0"
if pkgrelease:
current_path = __path__[0]
new_path = os.path.join( current_path, pkgrelease )
init_path = os.path.join( new_path, "__init__.py" )
__path__[:] = [new_path]
initf = open( init_path )
exec compile( initf.read(), init_path, "exec" ) in globals()
initf.close()
else:
raise ImportError( "Could not find [%s] package version" % os.path.basename(__path__) )
__load()
del __load
在 python2
这工作正常,包被重定向到版本 1_0_0
,并且在那个版本 __init__
文件中保留并设置像 __version__
这样的东西globals()
。但我也知道有一种更好的方法可以实现我在这里想要实现的交叉兼容。由于 exec 编译语句,这在 python3 中不起作用。
我找到了一种适用于两者的解决方案 py2/3。只需要调整 exec
函数来接受 globals()
一个参数。这显示 here in the docs。这是修改后的代码:
def load():
import os
pkgrelease = "mypkg-1_0_0"
current_path = __path__[0]
new_path = os.path.join( current_path, pkgrelease )
init_path = os.path.join( new_path, "__init__.py" )
__path__[:] = [new_path]
initf = open(init_path)
module = compile(initf.read(), init_path, "exec")
exec(module, globals())
initf.close()
load()
del load
mypkg/
├── mypkg-1_0_0/
│ ├── __init__.py
├── __init__.py
以上目录是我的模块目录的示例。主模块 mypkg
包含所有子版本。当我执行 import mypkg
时,__init__
文件旨在将导入重定向到正确的版本,而 运行 目标版本 __init__
文件并将属性设置为 globals()
这是 mypkg
中的 __init__.py
的样子:
def __load():
import os
pkgrelease = "mypkg-1_0_0"
if pkgrelease:
current_path = __path__[0]
new_path = os.path.join( current_path, pkgrelease )
init_path = os.path.join( new_path, "__init__.py" )
__path__[:] = [new_path]
initf = open( init_path )
exec compile( initf.read(), init_path, "exec" ) in globals()
initf.close()
else:
raise ImportError( "Could not find [%s] package version" % os.path.basename(__path__) )
__load()
del __load
在 python2
这工作正常,包被重定向到版本 1_0_0
,并且在那个版本 __init__
文件中保留并设置像 __version__
这样的东西globals()
。但我也知道有一种更好的方法可以实现我在这里想要实现的交叉兼容。由于 exec 编译语句,这在 python3 中不起作用。
我找到了一种适用于两者的解决方案 py2/3。只需要调整 exec
函数来接受 globals()
一个参数。这显示 here in the docs。这是修改后的代码:
def load():
import os
pkgrelease = "mypkg-1_0_0"
current_path = __path__[0]
new_path = os.path.join( current_path, pkgrelease )
init_path = os.path.join( new_path, "__init__.py" )
__path__[:] = [new_path]
initf = open(init_path)
module = compile(initf.read(), init_path, "exec")
exec(module, globals())
initf.close()
load()
del load