我有一个带有__init__.py的Python包,它导入一些东西作为包API公开.

# __init__.py

from .mymodule import MyClass
# ...

我还希望能够将该包用作命令行应用程序,如python -m mypackage中所示,因此我有一个__main__.py文件用于此目的:

# __main__.py

if __name__ == '__main__':
    from .main import main
    main()

到目前为止还不错.问题是,当包作为这样的程序运行时,我希望能够导入任何子模块,即在加载某些第三方依赖项之前更改一些环境变量.

我不知道如何做到这一点,至少不以合理的方式.理想情况下,我想做以下事情:

# __init__.py

def thePackageIsRunningAsAnApplication():
    # ???

def prepareEnvironment():
    # ...

if thePackageIsRunningAsAnApplication():
    prepareEnvironment()

from .mymodule import MyClass
# ...

问题是我认为thePackageIsRunningAsAnApplication()不能实现.通常的__name__ == '__main__'在这里不起作用,因为正在运行的主模块是__main__.py,而不是__init__.py.事实上,我更希望在__main__.py中定义并运行prepareEnvironment,但我不知道如何在__init__.py加载内部模块之前运行prepareEnvironment.

might(实际上不确定)通过延迟加载模块上的依赖项,或以某种方式延迟内部模块加载或其他方式来解决这个问题,但我更愿意避免这样做.

编辑:再仔细想想,延迟加载可能也不起作用.在这个例子中,MyClass是一个类,而不是一个子模块,所以我不能懒洋洋地加载它.此外,MyClass碰巧继承self 提到的第三方依赖项的类,因此我甚至无法在不加载它的情况下定义它.

推荐答案

添加一个单独的入口点来作为脚本运行代码可能是有意义的,而不是使用__main__.py,正如您所注意到的,__main__.py只能在包的__init__.py完全加载后运行.

位于顶层的简单脚本(如run_mypackage.py)可以包含环境变量调整代码,然后可以导入并运行包.

def prepare_environment():
    ...

if __name__ == "__main__":
    prepare_environment()            # adjust the environment firstt

    from mypackage.main import main  # then load the package afterwards
    main()

Python相关问答推荐

如何在Python中并行化以下搜索?

SQLAlchemy Like ALL ORM analog

考虑到同一天和前2天的前2个数值,如何估算电力时间序列数据中的缺失值?

具有相同图例 colored颜色 和标签的堆叠子图

从源代码显示不同的输出(机器学习)(Python)

如何根据rame中的列值分别分组值

如何使用Azure Function将xlsb转换为xlsx?

提取数组每行的非零元素

应用指定的规则构建数组

提取最内层嵌套链接

设置索引值每隔17行左右更改的索引

上传文件并使用Panda打开时的Flask 问题

.awk文件可以使用子进程执行吗?

具有不同坐标的tkinter canvs.cocords()和canvs.moveto()

如何计算Pandas 中具有特定条件的行之间的天差

Django-修改后的管理表单返回对象而不是文本

as_index=False groupBy不支持count

使用pytest测试是否缺少导入

Df.Drop_Duplates(),以极点表示?

来自Scipy的各种样条线插值器之间有什么不同?