今日内容概要
- 迭代取值与索引取值的差异
- 模块简介
- 导入模块的两种语法句式
- 导入模块句式的其他用法
- 循环导入问题
- 模块查找顺序问题
迭代取值与索引取值的差异
各自的优缺点
索引取值:
优势:可以重复取值
缺点:无法对无序容器取值,eg:字典,集合
迭代取值:
优势:对任何数据类型都可以用的取值方式
缺点:无法做到重复取值,只能按照开始的方向挨个取下去
模块的简介
思考
如何理解模块?
模块就是程序。模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法。
每个扩展名为.py的Python程序都是一个独立的模块。
-
模块的分类
1.内置模块 解释器自带的,使用者直接可以使用的模块 2.自定义模块 需要我们自己写的模块 3.第三方模块 别开发者写的模块,放在网上,如果要是有需要下载
-
模块的表现形式
1.py文件
2.含有多个py文件的文件夹
3.已被编译为共享库或DLL的c或C++扩展
4.使用c编写并链接到python解释器的内置模块
导入模块的两种句式
注意:在以后的工作中,模块文件名,我们要用英文
py文件在当作模块导入的时候不需要考虑后缀
-
导入模块的句式1
import 模块名
eg:
执行文件
被执行文件
运行结果
D:\python.3.6.4\python36.exe D:/pythonProject/day22/Module1.py
jason
Process finished with exit code 0
当我们开始运行执行文件的时候,import会先产生一个名称空间;然后被执行文件将自己执行会产生的名称都存储在名称空间中;Module1是指向被执行文件Module2中的名称;当我们使用Module1点加名称的时候,其实在在被执行文件中去找相关名称的数据值。
补充:如果一个程序中重复导入相同的模块的时候,导入模块语句只会执行一次
当执行文件中也出现了和被执行文件中相同的变量名的时候:
eg:
当执行文件中也有name的时候,是在执行文件名称空间中产生了一个name的名称,然后第二个print是找的自己名称空间的值
-
导入模块的句式2
from 模块名 import 模块名称空间里的名称
指名道姓的导入,而不是整个导入
eg:
代码底部执行顺序
先在执行文件中创建一个名称空间,然后在被执行文件中创建一个名称空间,当我们执行被执行文件中的代码,将执行过程中产生的名字存储在名称空间,然后执行文件中得到想要的执行空间中的名字
两种导入句式的优缺点
导入句式1(import 模块名)
优点:通过模块名加点的方式可以使用到模块里所有的名字,而且不会冲突
缺点:全都可以点出来,但是有时候我们不想用到的一些名字也能被使用
导入句式2(from 模块名 import 使用的名字)
优点:可以指名道姓的,根据我们需求使用模块里的名字,而且不用加前缀
缺点:名字很容易产生冲突(绑定关系会被修改)
先是绑定被执行文件中的money,但是后来执行文件中出现了同样的money名称,就会与之前的1000断开绑定
补充知识
-
起别名
情况一
(与别人的模块名重名了)eg:
from Module2 import money as m print(m) # 也能正常的使用模块
情况二
(原来的模块名太复杂)eg:
import Module2 as M print(M.name)
-
导入多个模块
一共有两种方式
方式一
eg:
import time, sys, os
方式二
eg:
import time import sys import os
如果你想要的模块功能相似建议用方法一,不相似建议用方式二
-
全导入
需求:需要使用模块名称空间中很多名字 并且只能使用from…import句式
from md import * # 星号表示所有
ps:针对星号的导入还可以控制名字的数量
在模块文件中可以使用__all__ = [字符串的名字]控制*能够获取的名字
循环导入问题
思考
如何理解循环导入问题
循环导入就是两个模块相互导入
举例说明
解释:
解决方法
让Module2中在导入Module1之前就先产生一个名称
循环导入将来尽量避免出现!!! 如果真的避免不了 就想办法让所有的名字在使用之前提前准备好
判断文件类型
在以后我们让我们代码运行起来的肯定不止一个文件
在所有的py文件中都会自带双下name的内置名
当py文件是执行文件的时候 name__的结果是__main
当py文件是被导入文件的时候 __name__的结果是模块名(文件名)
双下name主要用于开发模块的作者测试自己的代码使用
但是如果我们在使用模块的时候,被执行文件中有开发者自己的测试执行代码的时候,我们使用模块的时候,就会是测试结果;而我们使用模块是使用其功能去实现我们自己想要的结果
所以有个方法可以实现功能和测试分开
if name == ‘main’:
当文件是执行文件的时候才会执行if的子代码
因为pycharm知道这个是很常用的,所以搞了一个快捷方式直接编写main按tab键自动补全
模块查找顺序
内存>>>内置>>>sys.path(系统环境)
1.导入一个文件 然后在导入过程中删除该文件 发现还可以使用
import Module2
import time
time.sleep(15)
print(Module2.name) # 还是可以打印出名字,因为内存还有;但是如果再次运行就会报错
2.创建一个跟内置模块名相同的文件名
输出结果
Traceback (most recent call last):
File "D:/pythonProject/day22/Module1.py", line 2, in <module>
print(time.name)
AttributeError: module 'time' has no attribute 'name'
这里的自定义模块和内置模块冲突了
创建模块文件的时候尽量不要与内置模块名冲突
3.导入模块的时候一定要知道谁是执行文件
所以的文件都是按照路径来的
如果内存和内置里都没有就会去sys.path中找
eg:
import sys
# sys.path.append(r'D:\pythonProject\day22\xxx')
print(sys.path)
'''
['D:\\pythonProject\\day22',
'D:\\pythonProject\\day22',
'D:\\PyCharm 2021.1.3\\plugins\\python\\helpers\\pycharm_display',
'D:\\python.3.6.4\\python36.zip',
'D:\\python.3.6.4\\DLLs',
'D:\\python.3.6.4\\lib',
'D:\\python.3.6.4',
'D:\\python.3.6.4\\lib\\site-packages',
'D:\\PyCharm 2021.1.3\\plugins\\python\\helpers\\pycharm_matplotlib_backend']
'''
当在sys.path中查找的时候,只要第一个不是那后面肯定也不是。
我们在day22下新建一个xxx包,然后在包下创建一个py文件,由于md.py文件与Module1.py不是同一级,所以是找不到这个模块的,这个时候,我们可以通过sys.path列表加一个md.py的路径进去,这样就可以找到了
pycharm会自动将项目的根目录添加到sys.path中
通用的方式
sys.path.append(目标文件所在的路径)
还有一种方法,通过from…import…
from 文件的相对路径 import 模块名
eg:
from xxx import md
print(md.name) # 也是可以找到
如果py文件在很多包的下面,那可以通过级别依次点的形式找