前言
问题
为什么存在导入语句?
python能够使用import语句导入哪些东西?
导入时出现ModuleNotFoundError: No module named 'xxx'
错误的原因,导入的模块的路径查找顺序?
导入语句的几种形式及注意点
sys模块与导入路径关系
__init__.py文件的作用
if __name__=='__main__':
的使用
预备知识
包、模块的概念
重点
导入语句格式及注意点
推荐的导入方式
1. 导入语句的必要性
模块复用——-减少代码冗余、提高开发效率
2. 导入的对象
- 模块文件(.py文件)
- 导入整个文件
- 导入变量
- 导入函数
- 导入类
- C或C++扩展(已编译为共享库或DLL文件)
- 包(包含多个模块,一定包含
__init__.py
文件) - 内建模块(使用C编写并已链接到Python解释器中)
3. 模块的搜索路径
出现ModuleNotFoundError: No module named 'xxx'
问题一定是因为在sys.path
返回的所有路径中搜索不到模块的名字
sys.path
指定了模块的搜索路径的字符串列表。sys模块包含了与python解释器和它的环境有关的函数, 里面有个 sys.path属性。它是一个list.默然情况下python导入文件或者模块的话,他会先在sys.path
里找模块的路径。如果没有的话,程序就会报错。
通过sys.path
指定了模块的搜索路径的字符串列表。
sys.path.append()
方法添加模块的搜索路径,sys.path
作用域只是当前进程,进程结束后就失效了。
例:sys.path.append('')
将当前路径加入到模块的搜索路径
3.1 模块的搜索路径的组成
Python搜索模块的路径是由四部分构成的:程序的主目录、PATHONPATH目录、标准链接库目录和.pth文件的目录,这四部分的路径都存储在sys.path 列表中。
1,程序的主目录
主目录是指包含程序的顶层脚本的目录,Python首先会到主目录中搜索模块。
因为主目录总是第一个被搜索,如果模块完全处于主目录中,所有的导入都会自动完成,而不需要单独配置路径。
2,PATHONPATH目录
PATHONPATH目录是指PATHONPATH环境变量中配置的目录,是第二个被搜索的目录,Python会从左到右搜索PATHONPATH环境变量中设置的所有目录。
3,标准链接库目录
标准链接库目录是Python按照标准模块的目录,是在安装Python时自动创建的目录,通常不需要添加到PYTHONPATH目录中。
4,路径文件(.pth文件)
在模块搜索目录中,创建路径文件,后缀名为.pth,该文件每一行都是一个有效的目录。Python会读取路径文件中的内容,每行都作为一个有效的目录,加载到模块搜索路径列表中。简而言之,当路径文件存放到搜索路径中时,其作用和PYT)HONPATH环境变量的作用相同。
如果运行在Windows和Python3.0中,如果Python安装目录的顶层是C:\Python30,那么可以把自定义的路径文件 mypath.pth 放到该目录中。
也可以放到标准库所在位置的sitepackages子目录中(C:\Python30\Lib\sitepackages),来扩展模块的搜搜路径。
3.2 设置模块的搜索路径
上述四种模块搜索路径,能够配置的选项只有PYTHONPATH环境变量和路径文件。
- 例如,在Windows平台上,创建PYTHONPATH环境变量,设置变量的值,两个目录使用分号隔开:
C:\pycode\utilities;D:\pycode\package1
- 也可以创建一个名为 C:\Python30\pydirs.pth的文本文件,其内容如下所示:
C:\pycode\utilities
D:\pycode\package1
sys.path.append(absolute_or_relative_path_string)
将当前路径加入到模块的搜索路径,一般在代码编写的最前面———————————————————-推荐
__init__.py
的主要作用
Python中package的标识,不能删除
定义
__all__
用来模糊导入编写Python代码(不建议在
__init__
中写python模块,可以在包中在创建另外的模块来写,尽量保证__init__.py
简单)
__init__.py
文件的作用是将文件夹变为一个Python模块,Python 中的每个模块的包中,都有__init__.py
文件。
通常__init__.py
文件为空,但是我们还可以为它增加其他的功能。我们在导入一个包时,实际上是导入了它的__init__.py
文件。这样我们可以在__init__.py
文件中批量导入我们所需要的模块,而不再需要一个一个的导入。
4. 导入语句
4.1 导入模块
导入语法
导入整个模块(.py文件)
格式1:
import module_name
格式2:
import package_name.module_name
当模块在某个包内导入某个模块的类(变量与函数类似)
格式1:
import module_name.class_name
格式2:
from package_name.module_name import class_name
格式3:
import package_name.module_name.class_name
当类所在模块模块在某个包内格式4:
from package_name.module_nameimport class_name
当类所在模块模块在某个包内
if __name__=='__main__':
的使用
- if name == ‘main‘ 我们简单的理解就是: 如果模块是被直接运行的,则代码块被运行,如果模块是被导入的,则代码块不被运行。
- 作用
- 作为模块测试—–测试当前.py文件的功能
if __name__==__main__:
如果模块是被导入的,则代码块不被运行的原因- 在当前模块直接执行
print(__name__)
的结果永远是:__main__
- 在当前模块被别的模块import导入执行时
__name__
结果是:[包名.]模块名 - if判断
__name__
不等于__main__
,故不执行其下的代码,导入时执行了判断,只是不符合条件
- 在当前模块直接执行
查看导入的模块的路径
语句:module_name.__file__
如:
import random
random.__file__
需要说明的是,并不是所有模块都是使用 Python 语言编写的,有些与底层交互的模块可能是用 C 语言编写的,而且是 C 程序编译之后的效果,因此这种模块可能没有 file 属性,如sys模块。
4.2 导入包
格式1:import package_name 导入包下的__init__.py
文件
(1)如果包下的__init__.py
文件没有写任何语句,是一个空文件,这种格式无法调用任何包内的模块
例子:
文件
# my_package_1包下的__init__.py文件
# my_package_1包下的test01.py文件
def my_test_1():
print('这里是my_package_1包下的test01.py文件')
# my_import_package_1.py文件
import my_package_1
my_package_1.test01.my_test_1()
输出:
AttributeError: module 'my_package_1' has no attribute 'my_test_1'
原因:
__init__.py
是一个空文件,使用import package_name
该种导入方式无法使用包中的模块,保证__init__.py
导入模块写了import 导入语句(建议和__all__
连用,但是单独只有__all__
无法找到模块)
(2)如果包下的__init__.py
文件写了导入语句
例子:
# my_package_2包下的__init__.py文件
from . import test02
#__all__=['test02']
# my_package_2包下的test02.py文件
def my_test_2():
print('这里是my_package_2包下的test02.py文件')
# my_import_package_2.py文件
import my_package_2
my_package_1.test02.my_test_2()
输出:
这里是my_package_2包下的test01.py文件
原因:
__init__.py
是一个空文件,使用import package_name
该种导入方式无法使用包中的模块,保证__init__.py
导入模块写了导入语句或给__all__
赋值
建议:__init__.py
导入模块写import 导入语句(建议和__all__
连用,但是单独只写__all__
不写导入语句无法找到模块)
格式2:from package_name import module_name——-推荐
(1)对包下的__init__.py
文件没有要求,这种格式直接调用任何包内的某个模块
例子:
文件
# my_package_3包下的__init__.py文件
# my_package_3包下的test03.py文件
def my_test_3():
print('这里是my_package_3包下的test03.py文件')
# my_import_package_3.py文件
from my_package_3 import test03 #**********************************************
test03.my_test_3()
输出:
print('这里是my_package_3包下的test03.py文件')
格式3:from package_name import *
from package_name import *
调用时不需要写包名,引入过多有命名冲突问题
from package_name import *
导入的是
所有在
__init__.py
文件中__all__
列表变量的内容__init__.py
文件中import导入的模块__all__
列表与import导入同时使用,以__all__
列表为准同格式1:
import package_name
,需要保证__init__.py
有被调用的导入模块
问题
什么是内建模块?module ‘sys’ < built-in > is a built-in module,与普通的模块区别?为什么嵌入式版本python模块搜寻路径没有当前路径?
__init__.py
可以写哪些内容?作用是什么?有什么书写建议或规范?
相对导入与绝对导入问题
参考文章
1.【Python】 sys.path(环境变量)与init.py(https://blog.csdn.net/v_xchen_v/article/details/80393967)
2.Python 学习 第13篇:模块搜索路径和包导入(https://www.cnblogs.com/ljhdo/p/10674242.html)