python - __init__.py 代码被调用两次及其对包导入的意义

标签 python compilation initialization init python-module

我有一个简单的Python项目,用于学习两个文件__init__.py__main__.py 当我执行 python -m pkg_name 时 它同时运行 __init__.py__main__.py

当我执行python -m pkg_name.__init__.py 它调用 __init__.py 两次。

我想知道为什么当我调用__init__.py__init__.py被调用两次 是不是像java中的静态代码,当我们调用类时所有的数据 在静态代码中会自动触发。

Python 中 __init__.py 的相关性是什么,以及在导入/加载包或调用处理时执行它的好处。 请帮助我更好地理解这些概念。

"""Run a sequence of programs, testing python code __main__ variable

Each program (except the first) receives standard output of the
previous program on its standard input, by default. There are several
alternate ways of passing data between programs.

"""

def _launch():
    print('Pipeline Launched')


if __name__ == '__main__':
    print('This module is running as the main module!')
    _launch()
> __init__.py

"""This is the __init__.py file of pipleline package

Used for testing the import statements.


"""

print(__name__)
print('This is the __init__.py file of pipleline package')
print('Exiting __init__ of pipeline package after all initialization')

最佳答案

以下命令用于执行Python模块或包:

python -m module

其中module不带.py扩展名的模块/包的名称。

  • 如果名称与脚本匹配,则会进行字节编译并执行,
  • 如果名称与包含 __init__.py 文件和 __main__.py 文件的目录匹配,则该目录被视为 Python 包并首先加载。然后执行__main__.py脚本。
  • 如果名称包含点,例如:“mylib.mypkg.mymodule”,Python会浏览与点名称匹配的每个包和子包并加载它。然后它执行最后一个模块(或必须包含 __main__.py 文件的最后一个包)。

官方文档中有一个(简短的)描述:29.4. main — Top-level script environment .

你的问题

如果运行此命令:

python -m pkg_name

它加载(并运行)__init__.py__main__.py:这是正常行为。

如果运行此命令:

python -m pkg_name.__init__.py

如果您保留“.py”扩展名,它应该会失败。

如果它运行,该命令首先加载pkg_name包:它首先执行__init__.py。然后它再次运行。

关于python - __init__.py 代码被调用两次及其对包导入的意义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41421891/

相关文章:

c++ - GCC编译编译64位

Delphi:可以有条件地进行单元初始化吗?

c - valgrind 是否通过驱动程序跟踪内存初始化?

python - Django 查询以检索满足相关表聚合条件的行

python - 使用Python填充缺失数据

python - requests/httplib/urllib 返回 3 个不同的结果

python - 转义字符串然后在 jinja 中添加 html 标签

php - 我必须在 Windows 上编译 PHP 扩展才能在 Windows 上使用它吗?

python - 如何在 Windows 上为多个平台编译 cython 模块?

c# - Spring.Net 中的多个上下文