代码急转弯——python -m
在命令窗口中可用命令
python a.py
来执行python脚本a.py,还可以加上选项 -m 把 a.py 作为模块来执行,如
python -m a
【问题】是 -m 参数有何作用?
下面通过6条命令来加以说明。先来看看目录结构,
E:\dir1>tree /F
E:.
│ 1.txt
│ a.py
│ b.py
│ test.py
└──dir2
a.py
b.py
__init__.py
__main__.py
定义两个函数。to_file按照cond_str指定的内容生成一个名为fname的文本文件。cmd用于在python中执行一条终端命令cmd_str,命令采用输出重定向 >1.txt 将作为执行结果的输出文字保存到文本文件 1.txt 中,然后再显示出来。
import os
def cmd(cmd_str):
os.system(cmd_str + ' > 1.txt')
with open('1.txt', 'r') as f:
print(f.read())
def to_file(fname, cont_str):
with open(fname, 'w') as f:
f.write(cont_str)
# In[2]
to_file('hello.py', 'print("hello")')
cmd('python hello.py')
运行结果得到文件 hello.py,该文件中只有一行代码:print(“hello”)。
cmd(‘python hello.py’) 执行hello.py,运行结果如下,
hello
1、python a.py 与 python -m a.py
python a.py 执行 dir1/a.py。
s = '''import b
print('in a.py')'''
to_file('a.py', s)
cmd('python a.py')
运行结果
in b.py
in a.py
python -m a.py 也执行 dir1/a.py,而且有同样的结果,请阅读全文后回答为什么。
cmd('python -m a')
带有 -m 选项时,模块参数只写a.py的文件名a,不包括扩展名。
2、python dir 与 python -m dir
模块可以是文件,也可以是目录。
在目录dir2中建立两个文件,__init__.py和__main__.py。文件中有打印函数,目的是表明自己已被调用。
注意文件名前后的双下划线,对它们的调用由系统自动完成。
s = '''print('in dir2/__init__.py')'''
to_file('dir2/__init__.py', s)
s = '''print('in dir2/__main__.py')'''
to_file('dir2/__main__.py', s)
cmd('python dir2')
运行 python dir2 将自动调用__main__.py,结果如下,
in dir2/__main__.py
带参数 -m 时,将自动调用__init__.py 和__main__.py,多跑了一个文件。
cmd('python -m dir2')
运行结果
in dir2/__init__.py
in dir2/__main__.py
3、python dir/a.py 与 python -m dir.a
现在有两个 b.py,在 a.py 中的 import b 将导入 dir1/b.py,还是dir2/b.py?
取决于 sys.path[0]。
s = '''import b
# from . import b as b2
import sys
print(sys.path[0])
print('in dir2/a.py')'''
to_file('dir2/a.py', s)
s = '''print('in dir2/b.py')'''
to_file('dir2/b.py', s)
cmd('python dir2/a.py')
运行结果表明,python dir2/a.py将导入 dir2/b.py。
in dir2/b.py
E:\dir1\dir2
in dir2/a.py
python -m dir2/a.py 将导入 dir1/b.py,因为此时 sys.path[0] 的值为 E:\dir1。
cmd('python -m dir.a')
运行结果
in dir2/__init__.py
in b.py
E:\dir1
in dir2/a.py
所以,
执行 E:\dir1> python dir2/a.py 时,a 导入 dir2 中的模块 b,
执行 E:\dir1> python -m dir2/a.py 时,a 导入 dir1中的模块 b。
还有一个区别,
执行 E:\dir1> python dir2/a.py 时,a.py中不能有 from . import b as b2,
执行 E:\dir1> python -m dir2/a.py 时,可以有上述语句。
请删除 # from . import b as b2 语句左边的#号字母,观察运行结果。
小结,-m 选项的作用:
1)import b 中 b 位置;
2)【from . import xxx】 能不能执行。