如何通过命令行运行 Python 脚本文件,模块,包

    我被代码海扁署名-非商业-禁演绎
    阅读 11:22·字数 3414·更新 
    Bilibili 空间
    关注 950

    本节讲述的是通过命令行运行以文件,模块或包形式存在的 Python 脚本,至于如何运行代码,你可以查看如何通过命令行运行 Python 代码一节。

    运行 Python 脚本文件的命令

    针对不同的操作系统,你可以在命令行中输入pythonpython3(或者指向 Python 的一些别名),并给出包含 Python 脚本文件的路径以运行他们。

    Windows
    python <script>
    UNIX/Linux/macOS
    python3 <script>
    script 参数

    script参数可以是相对路径或绝对路径,他指向扩展名为py的 Python 文件,或一个包含__main__.py文件的文件夹,或包含__main__.pyzip压缩文件。

    通过命令行运行 Python 脚本文件

    script参数替换为某个包含 Python 代码的py文件,会让该脚本文件得以运行。事实上,Python 对需要运行文件的扩展名没有强制性要求,因此,允许py以外的扩展名,比如txt(文本文件)。

    下面是一个用于演示的 Python 脚本文件run.py,我们使用函数print和内置变量__file__来显示文件路径。

    run.py
    # 在命令行输入 python 或 python3,并给出 run.py 的相对或绝对路径,以执行 print 函数
    print(f'我被执行了?{__file__}')

    控制命令行跳转至文件run.py所在的目录,然后输入以下内容,文件中的 Python 代码将被执行。

    Windows
    python run.py
    我被执行了?\command_line\run.py
    UNIX/Linux/macOS
    python3 run.py
    我被执行了?/command_line/run.py

    通过命令行运行包含 Python 脚本文件 __main__.py 的 zip 文件或文件夹

    如果script参数指向一个zip文件或文件夹,并且zip文件根目录或文件夹包含特殊 Python 脚本文件__main__.py,那么脚本文件__main__.py将被执行,否则,你会获取类似于can't find '__main__' module in '…'这样的提示信息。

    Python 仅支持执行 zip 格式的压缩文件

    无论压缩文件的扩展名是什么,他应该是zip格式的。其余压缩格式,比如7zgziptar等,无法被 Python 正确执行,即便他们包含特殊的 Python 脚本文件__main__.py

    下面,我们准备了两个不同的__main__.py文件,分别放入文件夹run和位于文件夹zip的压缩文件run.zip中,文件夹run与文件夹zip位于同一目录。

    run/__main__.py
    # 在命令行输入 python 或 python3,并给出 run 文件夹的相对或绝对路径,以执行 print 函数
    print(f'__main__ 被执行了?{__file__}')
    zip/__main__.py
    # 在命令行输入 python 或 python3,并给出 run.zip 的相对或绝对路径,以执行 print 函数
    print(f'zip 被执行了?{__file__}')

    控制命令行跳转至文件夹runzip所在的目录,然后输入以下内容,文件夹run和文件run.zip中包含的__main__.py将被执行。

    Windows
    python run
    __main__ 被执行了?\command_line\run\__main__.py
    UNIX/Linux/macOS
    python3 run
    __main__ 被执行了?/command_line/run/__main__.py
    Windows
    python zip\run.zip
    zip 被执行了?\command_line\zip\run.zip\__main__.py
    UNIX/Linux/macOS
    python3 zip/run.zip
    zip 被执行了?/command_line/zip/run.zip/__main__.py

    运行 Python 模块,包的命令

    由于每一个py脚本文件都是一个 Python 模块,因此,以上描述的运行 Python 脚本文件可以被视为运行 Python 模块。这里,我们将介绍另一种方式,通过在命令行输入pythonpython3(或者指向 Python 的一些别名)并使用-m参数来运行 Python 模块或包。

    Windows
    python -m <module-name>
    UNIX/Linux/macOS
    python3 -m <module-name>
    module-name 参数值

    module-name参数值是 Python 模块或包的完全限定名(不需要在末尾书写.py),他可能因为 Python 模块搜索路径的改变而改变。

    模块

    想要了解模块的完全限定名,你可以查看Python 指南Python 模块的完全限定名一段。

    通过命令行运行 Python 模块

    如果module-name参数值给出的完全限定名对应了一个 Python 模块,那么该 Python 模块将被运行,在大部分情况下,其效果与直接运行模块对应的py脚本文件是一致的。由于在命令行中直接运行py脚本文件与通过-m参数运行 Python 模块,可能会获得不同的 Python 模块搜索路径,因此存在模块无法被定位的可能性。

    模块搜索路径

    想要了解-m参数对应的模块搜索路径,你可以查看Python 指南Python 脚本目录或当前目录一段。

    命令行 -m 参数表示的 Python 模块完全限定名可以包含某些特殊字符

    在正常的 Python 代码中,模块的完全限定名不能包含某些特殊字符,即使这些字符可以出现在文件系统的路径中,比如-,如果 Pythonpy脚本文件或相关文件夹的名称包含字符-,那么书写import all-words.all-verbs这样的导入语句是不可能的,因为-将导致语法错误。

    -m参数对 Python 模块完全限定名并没有强制性要求,你可以书写类似于完全限定名的路径,比如包含字符-的路径,原因在于这并不像书写 Python 代码一样涉及语法问题。

    在名称包含-的文件夹all-words中,我们创建一个名称包含-的 Python 脚本文件all-verbs.py,并为其编写代码。

    all-words/all-verbs.py
    # 在命令行输入 python -m 或 python3 -m,并给出 all-verbs 的“完全限定名”,以执行 print 函数
    print('这里是模块 all-verbs')

    控制命令行跳转至文件夹all-words所在的目录,然后输入以下内容,Python 脚本文件all-verbs.py将作为模块被运行。

    Windows
    python -m all-words.all-verbs
    这里是模块 all-verbs
    UNIX/Linux/macOS
    python3 -m all-words.all-verbs
    这里是模块 all-verbs

    通过命令行 -m 参数运行的 Python 模块需要具有对应的 py 脚本文件或 pyc 字节码文件

    需要指出的是,能够通过-m参数运行的 Python 模块需要具有对应的py脚本文件,或者编译后的pyc字节码文件。因此,运行某些内置 Python 模块将是不可行的,比如常见的sys内置模块。

    Windows
    python -m sys
    : No code object available for sys
    UNIX/Linux/macOS
    python3 -m sys
    : No code object available for sys

    通过命令行运行包含模块 __main__ 的 Python 包

    在 Python 3.1 或更高版本中,你可以将某个 Python 包的完全限定名赋值给module-name,以运行该 Python 包中的__main__模块。在 Python 3.4 或更高版本中,上述做法对于命名空间包(不包含__init__模块的 Python 包)同样有效。当被运行的 Python 包中缺少模块__main__时,你会获取类似于No module named ….__main__; '…' is a package and cannot be directly executed这样的提示信息。

    通过-m参数运行 Python 包,与运行包含__main__.py文件的zip压缩文件或文件夹类似,但他们可能会对应不同的 Python 模块搜索路径,这样的情况,我们在之前运行 Python 模块一段中讨论过。

    另外,由于 Python 包是一种特殊的模块,因此,一些关于运行 Python 模块的问题,同样适用于运行 Python 包。比如,包含字符-的“完全限定名”。

    下面,我们在all-words文件夹中,创建 Python 脚本文件__main__.py,并为其编写代码。

    all-words/__main__.py
    # 在命令行输入 python -m 或 python3 -m,并给出 all-words 的“完全限定名”,以执行 print 函数
    print('这里是 all-words 的 __main__ 模块')

    控制命令行跳转至文件夹all-words所在的目录,然后输入以下内容,__main__模块将被运行。

    Windows
    python -m all-words
    这里是 all-words 的 __main__ 模块
    UNIX/Linux/macOS
    python3 -m all-words
    这里是 all-words 的 __main__ 模块

    运行 Python 编译的 pyc 字节码文件

    在以上介绍的几种执行方式中,py文件可被替换为编译后的pyc字节码文件。比如,将名称为__main__.pyc的 Python 字节码文件放入文件夹或zip压缩文件中,以替换原有的__main__.py

    并非运行 __pycache__ 文件夹中编译的 pyc Python 字节码文件

    需要指出,这里所说的运行pyc,并不是指 Python 自动运行编译在__pycache__文件夹中的字节码文件,而是直接通过命令行运行pyc

    在使用py_compile模块将run.py编译为pyc文件后,控制命令行跳转至pyc文件所在的目录,输入命令以执行他。这里,我们假设编译的 Python 字节码文件的名称为run.pyc

    Windows
    python run.pyc
    我被执行了?\command_line\run.pyc
    UNIX/Linux/macOS
    python3 run.pyc
    我被执行了?/command_line/run.pyc

    Python py 脚本文件与 pyc 字节码文件的执行优先级

    如果你所执行的命令没有明确指出对格式的要求,比如通过-m参数执行,并且在文件夹或zip压缩文件中,存在名称相同的 Pythonpy脚本文件和pyc字节码文件(不是__pycache__文件夹中的),那么 Python 将默认优先执行py脚本文件,编译的 Pythonpyc字节码文件会被忽略。

    源码

    src/zh/command_line·codebeatme/python·GitHub

    讲解视频

    如何在命令行或终端运行 Python 脚本文件,包含 __main__.py 脚本文件的文件夹或 zip 压缩档案·BiliBili