python3 -m x和python3 x.py有何不同
1.如何使用python3 -m
# a表示当前路径下的a.py文件
python3 -m a
# src.package.a表示当前路径下的src/package/a.py文件
python3 -m src.package.a
2.sys.path说明
-
sys.path指定模块搜索路径的列表 -
pytho3 xx.py和python3 -m xx都会把当前路径添加到sys.path中 -
python3 str/x.py那么会把当前路径添/src加到sys.path中 -
import <package-name>或from <package-name> in <module-name>时,package-name会从sys.path的路径列表中查找。查找不到就报错
2.1 添加路径
import sys
path = "add_you_path"
# 添加到尾部
sys.path.append(path)
# 插入到最前[推荐]
sys.path.insert(0, path)
2.2 查看路径
import sys
print(sys.path)
3.区别
3.1.调用同级py文件
3.1.1 绝对路径导入
python3 -m x和python3 x.py效果都是相同的
3.1.1.1 文件详情
- path:
/Users/lxd670/test_python_m - 路径结构
.
├── a.py # 入口文件
└── b.py
- a.py文件内容
# 引入b模块
import sys
from b import test_b
if __name__ == "__main__":
print(sys.path)
test_b()
- b.py文件内容
def test_b():
print('is b fnunction')
3.1.1.2 使用python3 a.py
# 会把当前目录添加到sys.path中
['/Users/lxd670/test_python_m', 'xxx', 'xxx']
is b fnunction
3.1.1.3 使用python3 -m a
['/Users/lxd670/test_python_m', 'xxx', 'xxx']
is b fnunction
3.1.2 相对路径导入
python3 -m x和python3 x.py执行不了
报错ImportError: attempted relative import with no known parent package
这是因为相对导入是基于包的结构来工作的,而直接在命令行中运行单个.py文件时,Python 解释器不会将当前目录视为一个包。
3.1.2.1 文件详情
- path:
/Users/lxd670/test_python_m - 路径结构
.
├── a.py # 入口文件
└── b.py
- a.py文件内容
# 引入b模块
import sys
from .b import test_b
if __name__ == "__main__":
print(sys.path)
test_b()
- b.py文件内容
def test_b():
print('is b fnunction')
3.1.2.2 使用python3 a.py
python3 a.py无法执行内部使用相对路径的py文件。
['/Users/lxd670/test_python_m', 'xxx', 'xxx']
Traceback (most recent call last):
File "a.py", line 3, in <module>
from .b import test_b
ImportError: attempted relative import with no known parent package
3.1.2.3 使用python3 -m a
python3 -m a也无法执行内部使用相对路径的py文件(直接运行)。
cd .. && python3 -m test_python_m.a这样就可以运行了!
['/Users/lxd670/test_python_m', 'xxx', 'xxx']
Traceback (most recent call last):
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py", line 193, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/Users/lxd670/test_python_m/a.py", line 3, in <module>
from .b import test_b
ImportError: attempted relative import with no known parent package
3.2 调用不同级py文件
3.2.1 绝对路径导入[指定src模块]
3.2.1.1 文件详情
- path:
/Users/lxd670/test_python_m - 路径结构
├── a.py # 入口文件
├── c.py
└── src
├── b.py # 绝对导入src.c
└── c.py
- a.py文件内容
import sys
print(sys.path)
# 绝对路径导入[scr的b]
from src.b import test_b
if __name__ == "__main__":
test_b()
- c.py文件内容
def test_c():
print('is c fnunction[main]')
- src/b.py文件内容
# 绝对路径导入[scr的c]
from src.c import test_c
def test_b():
print('is b fnunction')
test_c()
- src/c.py文件内容
def test_c():
print('is c fnunction')
3.2.1.2 使用python3 a.py
['/Users/lxd670/test_python_m', 'xxx', 'xxx']
is b fnunction
is c fnunction
3.2.1.3 使用python3 -m a
['/Users/lxd670/test_python_m', 'xxx', 'xxx']
is b fnunction
is c fnunction
3.2.2 绝对路径导入[不指定模块]
如果把
a.py同级c.py文件删除了,那么就会报错。
因为sys.path只会/Users/lxd670/test_python_m查找c模块,而不会去/Users/lxd670/test_python_m/src中查找
如果想让c模块去/Users/lxd670/test_python_m/src查找,那么只需要sys.path.append("Users/lxd670/test_python_m/src")就行了(先删除/Users/lxd670/test_python_m/c.py文件)。
3.2.2.1 文件详情
- path:
/Users/lxd670/test_python_m - 路径结构
├── a.py # 入口文件
├── c.py
└── src
├── b.py # 绝对导入c
└── c.py
- a.py文件内容
import sys
print(sys.path)
# 绝对路径导入[scr的b]
from src.b import test_b
if __name__ == "__main__":
test_b()
- c.py文件内容
def test_c():
print('is c fnunction[main]')
- src/b.py文件内容
# 绝对路径导入[当前路径下的c]
from c import test_c
def test_b():
print('is b fnunction')
test_c()
- src/c.py文件内容
def test_c():
print('is c fnunction')
3.2.2.2 使用python3 a.py
变为了同级的c模块
['/Users/lxd670/test_python_m', 'xxx', 'xxx']
is b fnunction
is c fnunction[main]
3.2.2.3 使用python3 -m a
变为了同级的c模块
['/Users/lxd670/test_python_m', 'xxx', 'xxx']
is b fnunction
is c fnunction[main]
3.2.3 相对路径导入
3.2.3.1 文件详情
- path:
/Users/lxd670/test_python_m - 路径结构
├── a.py # 入口文件
├── c.py
└── src
├── b.py # 相对导入.c
└── c.py
- a.py文件内容
import sys
print(sys.path)
from src.b import test_b
if __name__ == "__main__":
test_b()
- c.py文件内容
def test_c():
print('is c fnunction[main]')
- src/b.py文件内容
# 相对路径导入
from .c import test_c
def test_b():
print('is b fnunction')
test_c()
- src/c.py文件内容
def test_c():
print('is c fnunction')
3.2.3.2 使用python3 a.py
['/Users/lxd670/test_python_m', 'xxx', 'xxx']
is b fnunction
is c fnunction
3.2.3.3 使用python3 -m a
['/Users/lxd670/test_python_m', 'xxx', 'xxx']
is b fnunction
is c fnunction
3.3 调用下级目录的py文件[入口文件]
上面都是在执行当前目录下的
a.py入口文件,现在把a.py移动到src目录下,并修改内容
3.3.1 相对路径导入
3.3.1.1 文件详情
- path:
/Users/lxd670/test_python_m - 路径结构
.
├── b.py
└── src
├── a.py # 入口文件
└── b.py
- b.py文件内容
def test_b():
print('is b fnunction[main]')
- src/a.py文件内容
import sys
print(sys.path)
# ---------- 使用了相对入
from .b import test_b
if __name__ == "__main__":
test_b()
- src/b.py文件内容
def test_b():
print('is b fnunction')
3.3.1.2 使用python3 src/a.py
注意: 会把
/Users/lxd670/test_python_m/src添加到环境变量,并不是当前命令的路径的/Users/lxd670/test_python_m
python3 src/x.py无法执行内部使用相对路径的py文件。3.1.2 相对路径导入
['/Users/lxd670/test_python_m/src', 'xxx', 'xxx']
Traceback (most recent call last):
File "src/a.py", line 3, in <module>
from .b import test_b
ImportError: attempted relative import with no known parent package
3.3.1.3 使用python3 -m src.a
在
src/a.py中使用from .b import test_b,这里的.指的是当前包,也就是src这个目录被视为一个包。所以相对导入会在src这个包内查找b.py文件,而不是在上级目录中查找。
如果想要导入上级目录中的b.py文件,需要使用绝对导入。把from .b import test_b改为from b import test_b
['/Users/lxd670/test_python_m', 'xxx', 'xxx']
is b fnunction
3.3.2 绝对路径导入
3.3.2.1 文件详情
- path:
/Users/lxd670/test_python_m - 路径结构
.
├── b.py
└── src
├── a.py # 入口文件
└── b.py
- b.py文件内容
def test_b():
print('is b fnunction[main]')
- src/a.py文件内容
import sys
print(sys.path)
# ---------- 使用了绝对导入
from b import test_b
if __name__ == "__main__":
test_b()
- src/b.py文件内容
def test_b():
print('is b fnunction')
3.3.2.2 使用python3 src/a.py
因为添加的是
/Users/lxd670/test_python_m/src到sys.path中,所以查找的还是/Users/lxd670/test_python_m/src/b.py
['/Users/lxd670/test_python_m/src', 'xxx', 'xxx']
is b fnunction
3.3.2.3 使用python3 -m src.a
获取了
/Users/lxd670/test_python_m的b.py
['/Users/lxd670/test_python_m', 'xxx', 'xxx']
is b fnunction[main]

浙公网安备 33010602011771号