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.pathpython的搜索模块路径集,是一个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的模块的导入和包的导入相关推荐

  1. 太好了,一分钟带你分清Python的模块、库、包有什么联系和区别?

    Python的流行主要依赖于其有众多功能强大的库(Library),Python自带的标准库(Standard Library)可以满足大多数的基础需求,除了函数库以外,模块(Module)和包(Pa ...

  2. python中哪个符号用于从包中导入模块__学小易找答案

    [简答题]7个积分题 [单选题]5. Is it time for the meeting now? [单选题]result = lambda x: x * x print(result(5)) 以上 ...

  3. 设python中有模块m、如果希望同时导入m中的所有成员_python-模块

    先做几个练习题 练习计算一个四乘四矩阵的所有元素的和,以及对角线之和 #encoding=utf-8 a=[[1,2,3,4], [2,5,2,3], [1,5,3,2], [5,3,2,5] ] # ...

  4. python定义模块结束语_python-模块定义、导入、优化

    在Python中有一个概念叫做模块(module),比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块. 说的通俗点:模块就好比 ...

  5. 设python中有模块m、如果希望同时导入m中的所有成员_python基础入门——深蓝学院课后习题(三)...

    1.python函数有几部分组成?分别是什么? 函数名称 函数参数 表达式 函数返回值 2.可变参数在函数中如何表示?关键值参数是什么? * args 表示多个参数,只有值的可变参数 ** kwarg ...

  6. python 导入第三方包_python 导入第三方包---

    python导入第三方包的方法: 最重要的四件事: 1 import sys sys.path.append("..") 2要引入的包所在文件添加:__init__.py 3 fr ...

  7. android studio导入aar包,AndroidStudio导入本地aar文件

    平时写一些Demo玩的时候经常会用到重复的操作,比如打印Log,而Android原生的Log每次使用都要加上tag: Log.e(String tag, String msg); 而我习惯将tag全都 ...

  8. python queue模块安装_Python queue包_程序模块 - PyPI - Python中文网

    沃特?另一个消息队列? 考虑到消息队列的激增,人们可能倾向于相信 发明更多不是答案.使用现有的解决方案是 多次尝试与大多数现有的消息队列产品. 其他的失败(对于我们的用例). queuey是用来处理大 ...

  9. python settings模块安装_Python settings-helper包_程序模块 - PyPI - Python中文网

    在包中设置 在的模块目录中创建默认的/samplesettings.ini文件 您的包,带有一个[default]节和任何其他[sections] 您需要(即应用程序环境)[default] some ...

最新文章

  1. 如何开启和关闭开机自启动
  2. 千岛湖救人工程师再次暖心,“感动阿里奖”奖金都捐公益
  3. go mod依赖离线安装_go mod 无法自动下载依赖包的问题
  4. Linux 查看CPU,内存,硬盘
  5. 【嵌入式】C语言高级编程-变参函数(08)
  6. Linux学习笔记15—RPM包的安装OR源码包的安装
  7. mysql安装mac 压缩包_MySQL8.0安装详解(图文版)
  8. [转] Java内部类详解
  9. FPS游戏-罗技鼠标-通用的压枪宏
  10. 欧拉角Yaw、Pitch、Roll
  11. linux批量修改文件后缀
  12. UiPath手把手中文教程PDF
  13. Android H5交互实现拍照显示
  14. java forward方法_JAVA的服务重定向:使用forward()方法转发请求和使用sendRedirect()方法重定向的区别...
  15. Halcon 算子 convexity
  16. 一步解压缩目录下所有的压缩文件
  17. 阿里云短信功能网址链接
  18. GEOGJ型钢筋计应用工程监测
  19. SendMessage和PostMessage及Windows消息机制简介
  20. 哈工大2022秋计算机系统大作业——程序人生

热门文章

  1. 前端(慕课网)笔记一
  2. Ex 5_33 实现一个关于公式长度(其中所有文字总的出现次数)为线性时间的Horn公式可满足性问题_第十次作业...
  3. 基于webuploader.js的单图片上传封装
  4. BZOJ4569: [Scoi2016]萌萌哒
  5. 大型网站技术架构 读书笔记
  6. Linux 调度器发展简述
  7. 一步一步学习Ultimus - 三、系统设置
  8. python编程从入门到实践答案-《Python编程:从入门到实践》第五章 if语句 习题答案...
  9. 十大python开发软件-5款开发安全、高质量代码的优秀Python工具
  10. python在线工具-6 种 Python 数据可视化工具