关于import的正确用法
写一个中大型项目, 往往需要在项目根路径下安排多层级的子目录和文件, 然后各文件之间通过import
来相互连接.
各python文件之间如何通过import
连接?
我们要遵从一个规范:
所有python文件都要以项目根目录为起始点来import
, 当然除了目录下的__init__.py
文件, 该文件一般是通过from . import module
来使本目录和本目录下的module
文件做关联.
import
其他相关规范也需要注意:
- 所有
import
尽量放在代码文件的头部位置 - 每行
import
只导入一个对象 - 当我们使用
from xxx import xxx
时,import
后面跟着的对象要是一个package
(包对应代码目录)或者module
(模块对应代码文件), 不要是一个类或者一个函数 - 标准模块、第三方模块、自定义模块要按这个先后顺序排列, 三类之间使用一个空行分隔.
比如项目根路径为:
/path/project
项目的组织结构:
|
|
项目文件内容:
main.py
|
|
module.py
|
|
package1/module.py
|
|
package1/sub_package/module.py
|
|
package1/sub_package/__init__.py
|
|
package1/__init__.py
|
|
package2/module.py
|
|
package2/__init__.py
|
|
运行项目入口文件
|
|
输出结果为:
|
|
以上正确运行的约束条件为:
- 运行项目的入口程序文件, 必须在项目的根路径下;
import
的对象必须从项目根路径为起始点;- 如果
import
的对象为目录(package
), 则在目录下必须有__init__.py
文件, 且该文件中通过from . import module
的形式引入该目录下相关模块, 这样才可以使用相关模块, 否则虽然import package
时不会报错, 但使用package
下面的模块时就会提示找不到相关模块; - 如果
import
的对象为目录.文件
(package.module)这种形式, 目录下可以没有__init__.py
文件; - 如果以
from 目录 import 文件
这种形式, 目录下也可以没有__init__.py
文件;
值得解释的一个问题:
上面的python3环境并没有将项目根目录加入到sys.path
中, sys.path
指的是import
时python的查找路径, 为什么子目录中的python文件从项目根路径为起始点import
不会报错?
解答:
首先我们知道sys.path
中存储的是import
时python查找库的搜索路径, 通过打印该变量内容, 我们可知, ''
空字符串是第一个路径, 这个空字符串代表的是当前python文件的所在目录, 不论是绝对路径执行还是相对路径执行, 这个值都是一样的, 都是当前python文件所在的目录.
然后再回答一下上面的问题, 因为我们是以项目根路径下的python文件作为项目的执行文件的, 该文件的import
相当于把其他当前目录或各级子目录中的各个python文件中的代码(包括import
代码)都加载到了当前文件中, 所以子目录文件中的import
也是从项目根路径下开始的, 当然不会报错.
当然了, 我们要是单独执行子目录中的python文件, 就会报找不到模块的错误了.
还有一个问题, 以上我们部署到生成环境当然没问题, 问题是在项目开发过程中, 我们肯定是需要单独执行子目录中的python文件的, 这个时候改怎么配置呢?
解答:
把项目根目录加入到sys.path
中, 可通过如下方式设置:
|
|
这样子目录python文件在当前目录下找不到对象时, 就会去项目根路径下去找了.