python的模块的导入和包的导入
python导入视频教程
- egon知乎的python系列教程
- egon的博客园博客地址
- egon的51CTO博客地址
- egon的B站帐号,python学习教程
知乎专栏除了python教程,还有很多其他教程:
1 模块(module)
1.1 模块的定义
模块:用来从逻辑上组织代码(变量、函数、类、逻辑:实现一个功能),本质就是.py结尾的python文件(文件名:test.py,对应的模块名:test)
包:包用来从逻辑上组织模块的,本质就是一个目录(必须带有一个__init__.py文件)
- 在python中,
一个py文件
就是一个模块
- 文件名是
module.py
模块名是module
- 导入模块,可以
引用模块中已经写好的功能
如果把开发程序比喻成制造一台电脑,编写模块
就像是在制造电脑的零部件
,准备好零部件后,剩下的工作就是按照逻辑
把它们组装
到一起。
2 模块导入方法
2.1 import 语句和from-import语句
2.1.1 import 语句
1、直接导入模块名
import module_name
2、同时导入多个模块
同时导入多个模块有两种写法:
- 1)import导入多个模块,可以写成多行import语句(
推荐
)
import module1
import module2
import module3
...
import moduleN
- 2)还可以在一行导入,用
逗号
分开不同 模块(不推荐
)
import module1, module2, module3, ..., moduleN
推荐使用第一种导入多个模块,更规范、可读性更强
2.1.2 from-import语句
1、把模块下所有的方法和变量都导入(不推荐
)
from module_alex import *
2、指定导入模块下的需要用到的方法属性等(推荐
)
from module_alex import m1, m2, m3
2.1.3 其他导入语句as
模块导入的时候还可以通过as语句
起个别名
from module_alex import logger as logger_shl
通过定义别名,也可以防止在当前定义的函数logger名字相同而覆盖我们导入的logger。或者直接使用import module_alex; module_alex.logger
这种写法导入,也是可以避免重名带来的覆盖影响!
2.2 自定义同级目录的模块导入
下面我们想要在main.py
文件中应用foo.py模块中的功能
,需要使用import foo
2.2.1 使用import导入实例
1、文件目录结构
(base) shl@zhihui-mint:~/project$ tree
.
├── foo.py # 自定义的模块module
└── main.py # 在main.py文件中导入引用foo模块
2、自定义模块foo.py
文件中定义的内容
x = 1def get():print(x)def change():global xx = 0class Foo:def func(self):print('from the func')
3、在main.py文件中
中引用foo.py模块中的功能
,main.py文件中定义的内容
import foo #导入模块foo
a=foo.x #引用模块foo中变量x的值赋值给当前名称空间中的名字a
foo.get() #调用模块foo的get函数
foo.change() #调用模块foo中的change函数
obj=foo.Foo() #使用模块foo的类Foo来实例化,进一步可以执行obj.func()
import foo
可以理解成把foo.py
文件中所有的代码粘贴到main.py
文件中,然后解释一遍!
2.2.2 使用from-import导入实例
1、from moudle_name import func1, func2,...
还是上面的例子,from…import…与import语句基本一致,唯一不同的是:使用import foo导入模块后,引用模块中的名字都需要加上foo.作为前缀,而使用from foo import x,get,change,Foo则可以在当前执行文件中直接引用模块foo中的名字,如下
from foo import x,get,change #将模块foo中的x和get导入到当前名称空间
a=x #直接使用模块foo中的x赋值给a
get() #直接执行foo中的get函数
change() #即便是当前有重名的x,修改的仍然是源文件中的x
注意:
无需加前缀
的好处是使得我们的代码更加简洁
,坏处则是容易与当前名称空间中的名字冲突
,如果当前名称空间存在相同的名字,则后定义的名字会覆盖之前定义的名字。
2、from foo import *
:代表将foo中所有的名字都导入到当前位置
from foo import * #把foo中所有的名字都导入到当前执行文件的名称空间中,在当前位置直接可以使用这些名字a=x
get()
change()
obj=Foo()
3、上面通过*
导入的所有的功能,模块编写者可以通过定义__all__变量
来控制*
代表的意思:
如下,把foo.py文件
中内容修改为:
#foo.py__all__ = ['x', 'get']
x = 1def get():print(x)
def change():global xx = 0class Foo:def func(self):print('from the func')
此时在main.py
中通过*导入:
from foo import * #此时的*只代表x和getx #可用
get() #可用
change() #不可用
Foo() #不可用
3 import导入的本质(路径搜索和搜索路径)
导入模块的本质就是把python文件解释一遍
import module_name ----> module_name.py----->module_name.py的路径 导入module_name就是要找到一个module_name.py的文件,就是找到是module_name.py文件的路径
3.1 python模块导入路径搜索规则
1、使用sys.path
是python的搜索模块
的路径集
,是一个list
,如下是我的python搜索的路径集:
(base) shl@zhihui-mint:~$ python
Python 3.8.3 (default, Jul 2 2020, 16:21:59)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['',
'/opt/ros/melodic/lib/python2.7/dist-packages',
'/home/shl/anaconda3/lib/python38.zip',
'/home/shl/anaconda3/lib/python3.8',
'/home/shl/anaconda3/lib/python3.8/lib-dynload',
'/home/shl/anaconda3/lib/python3.8/site-packages',
'/home/shl/anaconda3/lib/python3.8/site-packages/bar_chart_race-0.2.0-py3.8.egg',
'/home/shl/anaconda3/lib/python3.8/site-packages/torch2trt-0.1.0-py3.8.egg',
'/home/shl/anaconda3/lib/python3.8/site-packages/pycolmap-0.0.1-py3.8-linux-x86_64.egg']
>>>
2、导入模块的时候,就是搜索py文件的过程,先从第一个''
是空,表示在当前路径
下搜索,如果没有在从第二个路径下搜索,以此类推,如果没有找到就报没有该模块的错误!
如果想要导入的模块,一定要保证sys.path
的列表中包含要查找模块的路径
3、列表中的每个元素
其实都可以当作一个目录
来看:
- 在列表中会发现有
.zip或.egg
结尾的文件,二者是不同形式的压缩文件
,事实上Python确实支持从一个压缩文件中导入模块,我们也只需要把它们都当成目录
去看即可。 - sys.path中的第一个路径通常为
空
,代表执行文件所在的路径
- 为了确保某个py文件无论在何处都可以被导入,只要把该
.py文件
所在的目录添加到sys.path列表中即可!!!
3.2 搜索模块的路径与优先级
1、模块其实分为四个通用类别,分别是:
1)使用
纯Python
代码编写的py文件
2)包含一系列
模块的包
3)使用
C编写
并链接到Python解释器
中的内置模块
4)使用
C或C++
编译的扩展模块
2、模块导入的优先级
在导入一个模块时,如果该模块已加载到内存中
,则直接引用
,否则会优先查找内置模块
,然后按照从左到右
的顺序依次检索sys.path
中定义的路径
,直到找模块对应的文件为止,否则抛出异常。sys.path也被称为模块的搜索路径,它是一个列表类型
3.3 导入不同级目录的文件
还是上面的两个文件,让main.py
导入foo模块
,但是文件的位置发生了变化,如下:
(base) shl@zhihui-mint:~$ pwd
/home/shl
(base) shl@zhihui-mint:~$ tree project
project
├── foo.py
└── src└── main.py1 directory, 2 files
(base) shl@zhihui-mint:~$
我们的目的是在执行main.py文件
的时候能够正确导入foo模块
,因此只要在导入foo模块之前,把foo.py
所在的目录路径添加到python的搜索模块
的路径集
的列表中即可!详细过程见下面代码中的注释!
1、foo.py
文件内容:
x = 1def get():print(f"x value is: {x}")def change():global xx = 0class Foo:def func(self):print('from the func')
2、main.py
文件内容:
import sys
import os# sys.path
print(sys.path)
'''
['/home/shl/project/src',
'/opt/ros/melodic/lib/python2.7/dist-packages',
'/opt/ros/eloquent/lib/python3.6/site-packages',
'/home/shl/anaconda3/lib/python38.zip',
'/home/shl/anaconda3/lib/python3.8',
'/home/shl/anaconda3/lib/python3.8/lib-dynload',
'/home/shl/anaconda3/lib/python3.8/site-packages',
'/home/shl/anaconda3/lib/python3.8/site-packages/bar_chart_race-0.2.0-py3.8.egg',
'/home/shl/anaconda3/lib/python3.8/site-packages/torch2trt-0.1.0-py3.8.egg',
'/home/shl/anaconda3/lib/python3.8/site-packages/pycolmap-0.0.1-py3.8-linux-x86_64.egg']'''# __file__ 是当前执行文件的文件文件名
print(f"file name: {__file__}") # file name: main.py# os.path.abspath(file)获取文件的绝对路径
file_abspath = os.path.abspath(__file__)
print(file_abspath) # /home/shl/project/src/main.py# os.path.dirname(path) # 获取指定路径的父级目录
dir_path = os.path.dirname(os.path.abspath(__file__))
print(dir_path) # /home/shl/project/src# 如果连续获取父级目录,只要调用两次os.path.dirname(os.path.dirname(path))即可!
dir_path2 = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print(dir_path2) # /home/shl/project# 把我们要导入模块的py文件所在目录路径添加到sys.path列表中即可
# 当然我们只要添加dir_path2这个路径即可,上面只是为了清楚我们添加foo.py这个模块所在目录路径的过程!
sys.path.append(dir_path2)# 再次查看foo.py所在的目录/home/shl/project已经添加到了sys.path列表中!
print(sys.path)
'''
['/home/shl/project/src', # 当前main.py所在的路径
'/opt/ros/melodic/lib/python2.7/dist-packages',
'/opt/ros/eloquent/lib/python3.6/site-packages',
'/home/shl/anaconda3/lib/python38.zip',
'/home/shl/anaconda3/lib/python3.8',
'/home/shl/anaconda3/lib/python3.8/lib-dynload',
'/home/shl/anaconda3/lib/python3.8/site-packages',
'/home/shl/anaconda3/lib/python3.8/site-packages/bar_chart_race-0.2.0-py3.8.egg',
'/home/shl/anaconda3/lib/python3.8/site-packages/torch2trt-0.1.0-py3.8.egg',
'/home/shl/anaconda3/lib/python3.8/site-packages/pycolmap-0.0.1-py3.8-linux-x86_64.egg',
'/home/shl/project'] # 我们通过sys.path.append(dir_path2) 添加的路径,# 而我们要导入的模块foo就在/home/shl/project 这个目录下,因此此时可以导入foo模块'''import foo # 导入模块fooa = foo.x # 引用模块foo中变量x的值赋值给当前名称空间中的名字a
foo.get() # 调用模块foo的get函数
foo.change() # 调用模块foo中的change函数
obj = foo.Foo() # 使用模块foo的类Foo来实例化,进一步可以执行obj.func()
3、此时执行就可以正确导入foo模块了
,否则会报错:ModuleNotFoundError: No module named 'foo'
(base) shl@zhihui-mint:~/project/src$ python main.py
Traceback (most recent call last):File "main.py", line 60, in <module>import foo # 导入模块foo
ModuleNotFoundError: No module named 'foo'
(base) shl@zhihui-mint:~/project/src$
注意:
因为是从sys.path
的列表中从左到右
开始找的,如果比如此时其他路径中刚好也有一个和我们要导入的同名模块,此时就不会继续找了,因此解决方法就是用插入的方法。
把我们要添加的路径添加到列表的首位:
sys.path.insert(index=0, obj=dir)
#把路径dir添加到sys.path列表中的索引0的位置
4 导入包
1、写一个项目会建一堆的目录结构
,这个目录就是我们右键新建Pyhton Package
(有一个__init__.py文件
)
2、包
:用来从逻辑上组织模块
的,本质就是一个目录
(与普通目录的区别,就是包必须带有一个__init__.py文件
)
3、导入包的本质:
- 就是去解释这个包下的
__init__.py文件
- 或者说的更直接一点,导入包的本质就是去执行该包下的
__init__.py文件
4、总结:
导入模块
就是相当于把xxx模块对应的xxx.py
中的全部代码,在当前导入的位置解释一遍
(可以更通俗的理解就是把xxx.py中的全部代码粘贴到我们导入的这个位置)导入包
就是去执行包下的__init__.py文件
导入xxx模块
是解释xxx模块对应的xxx.py文件
,导入xxx包
是运行的是xxx包
下的__init__.py文件
4.1 导入包:就是执行包下的__init__.py文件
下面我们在main.py文件
中导入包module_test
,看一下结果
(base) shl@zhihui-mint:~$ pwd
/home/shl
(base) shl@zhihui-mint:~$ tree project
project
├── main.py
└── module_test└── __init__.py1 directory, 2 files
(base) shl@zhihui-mint:~$
1、main.py
文件中内容
import module_test
2、__init__.py
文件中内容:
print("in the package")
3、执行python module_test.py
文件
此时可以发现会在终端打印出:in the module
4.2 导入包下的模块
我们导入包的目的最终是要导入包下面的模块
,下面我们在包module_test
下再新建一个模块test.py
,然后我们在main.py
中导入该包下的test.py模块
,文件目录结构如下:
(base) shl@zhihui-mint:~$ pwd
/home/shl
(base) shl@zhihui-mint:~$ tree project
project
├── main.py
└── module_test├── __init__.py└── test.py1 directory, 3 files
(base) shl@zhihui-mint:~$
4.2.1 测试导入包中的模块1
1、main.py
文件内容:
import module_testmodule_test.test.func()
2、test.py
文件内容:
def func():print("in the test")
3、__init__.py
文件内容:
print("in the package")
4、此时执行main.py
文件,结果如下:
(base) shl@zhihui-mint:~/project$ python main.py
in the package
Traceback (most recent call last):File "main.py", line 3, in <module>module_test.test.func()
AttributeError: module 'module_test' has no attribute 'test'
(base) shl@zhihui-mint:~/project$
会发现找不到test模块
,这是因为:
导入包的本质是执行
__init__.py
文件,我们发现__init__.py
文件中的print("in the package")
是被正确执行了因此,我们需要在
__init__.py
文件中定义导入test.py
文件的模块的
4.2.2 测试导入包中的模块2
1、只需要修改__init__.py
文件内容为如下:
print("in the package")# 相对导入,从当前目录下导入test模块
from . import test# import test # __init__.py和test.py是同级目录,因此__init__.py文件中肯定能够导入test.py模块
# test <- test.py all code ,import test就是把test.py中的所有代码加载到当前位置,然后赋值给test变量
注意:
按理说直接在__init__.py
文件中直接导入import test
就可以,但是egon在讲解的时候依旧是找不到test
模块,我自己测试也是,因此还是推荐使用from . import test
这种相对导入的方式
!!!
2、此时再执行main.py文件
,即可正确导入module_test包
下的test.py
模块,执行结果如下:
(base) shl@zhihui-mint:~/project$ python main.py
in the package
in the test
(base) shl@zhihui-mint:~/project$
当然,你也可以在main.py
文件中直接导入包下的test.py
模块,不通过导入包的方式,如下main.py
中直接导入包下的模块也是可以的:
#import module_test.test as test#test.func()from module_test.test import funcfunc()
5 导入优化
import module
module.test() 有100处用到了这个代码,就需要每次调用先去找module这个模块对应的module.py对应的路径,然后导入test()函数,效率就比较低
from module import test
这样就只有第一次需要找路径,后面就直接使用test()函数了!
6 模块的分类
- 1)标准库(python解释器自带的内置模块,例如sys、os等)
- 2)开源模块(或第三方模块,例如github上的一些python开源的模块)
- 3)自定义模块
在home目录下有两个目录:
- FRecogintion
- FRecogintionTrain
现在再FRecogitionTrain/train.py脚本中想导入FRcoginition中的其他模块,可以这么写:
1)再FRecogitionTrain目录下新建一个脚本,_init_paths.py
,在里面定义把FRecogintion模块添加到系统环境变量中
,如下:
#coding=utf-8
import sysdiluface_root = '/home/suihl/FRecogintion'
sys.path.insert(0, diluface_root)
sys.path.insert(0, '.')
2、然后在main.py文件中导入_init_paths.py即可:
from ._init_paths import *
1)main.py中内容:
from test.test import my_testmy_test()
2)test.py中内容:
注意:
因为是main.py去调用test.py脚本,因此相当于是把test.py脚本粘贴到main.py中,因此读取路径也是相对main.py的当前路径,所以读取文件路径是./test/add.txt
3)add.txt中内容:
test
然后执行main.py,报错:
解决方式:在test目录下新建一个__init__.py文件
,文件内容为空,此时就可以正确导入了!
python的模块的导入和包的导入相关推荐
- 太好了,一分钟带你分清Python的模块、库、包有什么联系和区别?
Python的流行主要依赖于其有众多功能强大的库(Library),Python自带的标准库(Standard Library)可以满足大多数的基础需求,除了函数库以外,模块(Module)和包(Pa ...
- python中哪个符号用于从包中导入模块__学小易找答案
[简答题]7个积分题 [单选题]5. Is it time for the meeting now? [单选题]result = lambda x: x * x print(result(5)) 以上 ...
- 设python中有模块m、如果希望同时导入m中的所有成员_python-模块
先做几个练习题 练习计算一个四乘四矩阵的所有元素的和,以及对角线之和 #encoding=utf-8 a=[[1,2,3,4], [2,5,2,3], [1,5,3,2], [5,3,2,5] ] # ...
- python定义模块结束语_python-模块定义、导入、优化
在Python中有一个概念叫做模块(module),比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块. 说的通俗点:模块就好比 ...
- 设python中有模块m、如果希望同时导入m中的所有成员_python基础入门——深蓝学院课后习题(三)...
1.python函数有几部分组成?分别是什么? 函数名称 函数参数 表达式 函数返回值 2.可变参数在函数中如何表示?关键值参数是什么? * args 表示多个参数,只有值的可变参数 ** kwarg ...
- python 导入第三方包_python 导入第三方包---
python导入第三方包的方法: 最重要的四件事: 1 import sys sys.path.append("..") 2要引入的包所在文件添加:__init__.py 3 fr ...
- android studio导入aar包,AndroidStudio导入本地aar文件
平时写一些Demo玩的时候经常会用到重复的操作,比如打印Log,而Android原生的Log每次使用都要加上tag: Log.e(String tag, String msg); 而我习惯将tag全都 ...
- python queue模块安装_Python queue包_程序模块 - PyPI - Python中文网
沃特?另一个消息队列? 考虑到消息队列的激增,人们可能倾向于相信 发明更多不是答案.使用现有的解决方案是 多次尝试与大多数现有的消息队列产品. 其他的失败(对于我们的用例). queuey是用来处理大 ...
- python settings模块安装_Python settings-helper包_程序模块 - PyPI - Python中文网
在包中设置 在的模块目录中创建默认的/samplesettings.ini文件 您的包,带有一个[default]节和任何其他[sections] 您需要(即应用程序环境)[default] some ...
最新文章
- 如何开启和关闭开机自启动
- 千岛湖救人工程师再次暖心,“感动阿里奖”奖金都捐公益
- go mod依赖离线安装_go mod 无法自动下载依赖包的问题
- Linux 查看CPU,内存,硬盘
- 【嵌入式】C语言高级编程-变参函数(08)
- Linux学习笔记15—RPM包的安装OR源码包的安装
- mysql安装mac 压缩包_MySQL8.0安装详解(图文版)
- [转] Java内部类详解
- FPS游戏-罗技鼠标-通用的压枪宏
- 欧拉角Yaw、Pitch、Roll
- linux批量修改文件后缀
- UiPath手把手中文教程PDF
- Android H5交互实现拍照显示
- java forward方法_JAVA的服务重定向:使用forward()方法转发请求和使用sendRedirect()方法重定向的区别...
- Halcon 算子 convexity
- 一步解压缩目录下所有的压缩文件
- 阿里云短信功能网址链接
- GEOGJ型钢筋计应用工程监测
- SendMessage和PostMessage及Windows消息机制简介
- 哈工大2022秋计算机系统大作业——程序人生
热门文章
- 前端(慕课网)笔记一
- Ex 5_33 实现一个关于公式长度(其中所有文字总的出现次数)为线性时间的Horn公式可满足性问题_第十次作业...
- 基于webuploader.js的单图片上传封装
- BZOJ4569: [Scoi2016]萌萌哒
- 大型网站技术架构 读书笔记
- Linux 调度器发展简述
- 一步一步学习Ultimus - 三、系统设置
- python编程从入门到实践答案-《Python编程:从入门到实践》第五章 if语句 习题答案...
- 十大python开发软件-5款开发安全、高质量代码的优秀Python工具
- python在线工具-6 种 Python 数据可视化工具