【问题标题】:Reroute Python Module To Another Directory (Sub-version) on import导入时将 Python 模块重新路由到另一个目录(子版本)
【发布时间】:2020-04-10 05:07:53
【问题描述】:
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,而__version__ 等版本__init__ 文件中的内容被保留并设置在globals() 中。但我也知道有一种更好的方法来做我想要在这里实现的东西,它是交叉兼容的。由于 exec compile 语句,这在 python3 中不起作用。

【问题讨论】:

  • 你能告诉我更多关于这个__init__的信息吗?如果你想导入它,你会怎么做?
  • 有很多更好的方法可以做到这一点。即使在python2中
  • 当您导入 mypkg 时,何时决定加载哪个实现?
  • 这称为 xy 问题:您认为需要移植 exec 语句,但实际上您需要帮助修复它所代表的代码异味。
  • 请发布示例目录结构、您的用户导入的外观以及您想要实际导入的内容。您当前的代码是您现在如何实现重定向的示例。您正在寻找一种更便携的方式来进行重定向,而不一定要移植确切的代码。

标签: python python-3.x python-import compatibility


【解决方案1】:

我找到了一种适用于 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 2017-02-06
    • 2014-04-09
    • 2021-09-23
    • 1970-01-01
    相关资源
    最近更新 更多