Python -m 参数以及生僻运行命令汇总

最近在翻阅剖析Python源码的时候讲到了内部Python变量的实现,以及当运行Python命令时,隐藏在内部的一些过程,于是python3 --help之后对某些运行参数产生了一些疑问,还涉及到了包与模块的内容,略微生僻,特此整理记录下~

1. 大杂烩

旨在由用户直接执行的包含Python代码的纯文本文件通常称为**脚本(script),这是一个非正式术语,表示顶级程序文件。
另一方面,包含设计用于从另一个Python文件导入和使用的Python代码的纯文本文件称为
模块(modules)**。

1.1 使用importlib导入模块

1
2
import importlib
importlib.import_module('math')

当我们想要导入自己写的test.py中的函数hello时,我们可以这样曲线救国: 首先每个模块导入后是一个对象(object), 它里面的各个变量都是以属性(attr)的形式挂靠在里面, 所以我们可以使用getattr来找到制定的函数

hello = getattr(importlib.import_module('test'), 'hello') 等价于from test import hello

或者包中的某个模块:

ClassA = getattr(importlib.import_module('packege.module'), 'ClassA')等价于
from packege.module import ClassA

1.2 重新导入

1
2
3
import math
import math # Second import, which does nothing ,need to reload
importlib.reload(math)

这里的注意点,reload函数是一个模块对象,而不是一个字符串

1.3 使用 runpy.run_module() and runpy.run_path()运行脚本

1
2
3
import runpy
runpy.run_module(mod_name='hello')
runpy.run_path(file_path='hello.py')

1.4 使用exec()运行脚本

1
exec(open('hello.py').read())

1.5 python -c参数

1
python -c "import math;print(math.pi)"

2. Python -m 参数

-m参数显示为run library module as a script,常见于 Python3 -m http.server 8080

因为http标准库(已经存在于sys.path中),这也是包,我们用http.server来调用server文件并把它作为脚本来运行,运行其中__name__ == "__main__"部分

那假设我们是自己创建的的包呢,那也是同样的道理,我们python自问自答:python -m参数?,直接运行与-m运行的区别在于:
直接启动脚本是把脚本所在的目录添加在sys.path中
-m模块启动脚本是把你输入命令的目录(也就是当前路径),放到了sys.path属性中

3. 其他谈谈

3.1 当使用from module import * 语句时,希望对从模块或包导出的符号进行精确控制时,定义一个变量 all 来明确地列出需要导出的内容(强烈反对使用 from module import *

1
2
3
4
5
6
7
8
9
10
# somemodule.py
def spam():
pass

def grok():
pass

blah = 42
# Only export 'spam' and 'grok'
__all__ = ['spam', 'grok']

3.2 运行目录或压缩文件

如果你的应用程序已经有多个文件,你可以把你的应用程序放进它自己的目录并添加一个__main__.py文件。 举个例子,你可以像这样创建目录:

myapplication/
        spam.py
        bar.py
        grok.py
        __main__.py

如果__main__.py存在,你可以简单地在顶级目录运行Python解释器:python3 myapplication