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.pypython3 -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 xpython3 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 xpython3 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/srcsys.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_mb.py

['/Users/lxd670/test_python_m', 'xxx', 'xxx']
is b fnunction[main]
posted @ 2026-06-03 11:14  lxd670  阅读(4)  评论(0)    收藏  举报