python的import问题:绝对路径,相对路径,sys.path.append

python的import问题

- 原理
在Python中,一个.py文件就称之为一个模块(Module),包含.py文件的文件夹,且里面有一个__init_.py的文件夹称为包(Package)init.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,它的模块名就是包名。在python脚本被执行,python导入其他包或模块时,python会根据sys.path列表里的路径寻找这些包或模块。如果没找到的话,程序就会报错。

>>> import sys
>>> print(sys.path)
['', 'C:\\Users\\SONG\\Anaconda3\\python37.zip', 'C:\\Users\\SONG\\Anaconda3\\DLLs', 'C:\\Users\\SONG\\Anaconda3\\lib', 'C:\\Users\\SO
NG\\Anaconda3', 'C:\\Users\\SONG\\AppData\\Roaming\\Python\\Python37\\site-packages', 'C:\\Users\\SONG\\Anaconda3\\lib\\site-packages'
, 'C:\\Users\\SONG\\Anaconda3\\lib\\site-packages\\win32', 'C:\\Users\\SONG\\Anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\Users\\S
ONG\\Anaconda3\\lib\\site-packages\\Pythonwin']

程序中要导入包或模块就需要在这些路径中进行查找,分为三种情况:
① 当前执行脚本(主动执行,而不是被其他模块调用)所在路径。上面例子是在交互界面进行操作,没有执行脚本,所以为空字符串。
②python内置的标准库路径,PYTHONPATH。
③安装的第三方模块路径。

  • 分析
  • python module_0.py为前提
package_0
├── module_0.py
├── module_1.py
├── package_1
│   ├── module_2.py
│   ├── module_3.py
│   └── package_2
│       ├── module_21.py
│       └── module_22.py
└── package_3
    └── module_4.py

python module_0.py,即/home/…/package_0会被添加到 sys.path 中,可以通过该路径找到其他模块的,比如下面这些语句是不会报错的。

# module_0.py
import module_1
from package_1 import module_2
from package_1.package_2 import module_21

而下面的语句会报错:ModuleNotFoundError: No module named 'module_3’

# module_2.py
import module_3

原因:执行 python module_0.py 时,把路径(’/home/…/package_0’)添加到 sys.path 中,该路径下就不能在 module_2.py 中通过这种方式找到module_3,因为module_2.py 在路径/home/…/package_0/package_1下。

  • 绝对路径从当前执行脚本所在路径/…/需要的module
# module_2.py
from package_1 import module_3
# module_21.py
from package_1.package_2 import module_21
  • 相对路径
    单点表示引用的模块或包与当前模块在同一目录中(同一个包中)。
    两点表示在当前模块所在位置的父目录中。
# module_2.py
from . import module_3
from .package_2 import module_21
# module_21.py
from .. import module_2

下面的语句会报错:ValueError: attempted relative import beyond top-level package

# module_2.py
from ..package_3 import module_4

原因:试图在顶级包(top-level package)之外进行相对导入。也就是说相对导入只适用于顶级包之内的模块。
如果将 module_0.py 当作执行模块,则和该模块同级的 package_1 和 package_3 就是顶级包(top-level package),而 module_2 在package_1中,module_0、module_1和module_4都在 package_1之外,所以调用这三个模块时,就会报这个错误。
下面的语句会报错:ModuleNotFoundError: No module named ‘main.package_1’; ‘main’ is not a package

# module_0.py
from .package_1 import module_2

原因:用了相对导入的模块文件不能作为顶层执行文件,即不能 python module_0.py

  • sys.path.append
# module_2.py
sys.path.append(os.path.dirname(__file__))
import module_3
from package_2 import module_21
# module_2.py
sys.path.append(os.path.join(os.path.dirname(__file__), '../package_3'))
import module_4
  • 43
    点赞
  • 105
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值