Python模块导入
前言
Python是一门非常灵活的语言,代码组织可以从一个文件到一个目录,再到包含很多目录很多文件的工程。
当代码量越来越大的时候,要思考如何将代码模块化,如何能更加优雅的组织文件。
概念
Python中有模块的概念,对应的就是一个py文件;包的概念对应的就是一个目录,在Python2
中,
包中必须存在__init__.py
文件,在Python3
中这个规定已经不存在了,一个目录就是一个包。
导入
导入分为相对导入和绝对导入,在相对导入中又分为隐式导入和显示导入,隐式导入在Python3中已经废弃了,相对导入和绝对导入都是以包的概念来说的
隐式导入
没有指明从哪里导入的,例如标准库和第三方库可以直接导入,我们自己的文件也可以这样,但会带来一些歧义
假如存在这样一个目录
d1
│ main.py
└─d2
│ p1.py
│ p2.py
│ __init__.py
# main.py
import d2.p2
# p1.py
def hello():
print("hello")
# p2.py
import p1
p1.hello()
在d1文件夹下,运行main.py文件,python2是没有问题的,python3会报错,因为这种导入方式已经不支持了
如果在p2.py文件加上from __future__ import absolute_import,
同样也是会报错的
相对导入
from .xxx import yyy
.代表当前文件所在的目录
..代表当前文件的上一级目录或上一级目录的同级目录
...以此类推
from . import yyy
# 可以是从__init__.py文件中导入
绝对导入
from a.b.c import yyy
与相对导入不同的是绝对导入,标明了导入的文件的路径
如何用
Python提供了这两种导入方式,应该如何去组织代码。
官方推荐的是使用绝对导入,这样看着很清晰,Pycharm也提供了强大的重命名功能,一旦我们改变文件名或者目录名,import语句都会发生改变
我目前的方法是,在一个固定的,提供接口的模块内部使用相对导入,在外部的gui或者command接口文件使用绝对导入
绝对导入的路径应该怎么写?
在github上下载了几个项目,基本上是以下结构
project
| main.py
├─mod1
└─mod2
manage.py或者main.py在最外层,然后在main.py中导入模块
from mod1.package1 import xxx
from mod2.package2 import yyy
在运行的时候直接可以
python main.py 参数
入口文件main.py所在的文件夹会添加到sys.path的第一项,所以可以寻找到mod1和mod2包
以这种方式启动,入口文件中不能包含相对导入
如有错误,请大佬指正!
参考
https://ke.sifou.com/course/1650000037773462
https://segmentfault.com/a/1190000018032094