模块
生成式
列表生成式
一个快速产生列表的表达式
语法:[表达式 for in 遍历 if条件] (会从li依次取出所有值,如果满足条件,然后装到新列表中)
例如:new_list = [i for i in li if i > 20]
生成器表达式
函数体中yield关键字
yield 暂停函数的执行,还能返回一个值
生成器表达式
一种快速创建生成器的表达式
语法:(表达式 for in 循环 if 条件)
与列表生成式完全相同
详情看pycharm的第四周文件下的day04从第4行开始看
模块
目前使用函数来编写代码虽然大幅度降低了代码冗余,并且组织结构清晰多了,
但是随着项目功能的增加如果还将代码全放在一个文件中,将出现以下问题
1.维护性差
2.函数太多结构也不清晰,可读性差
3.对于相同功能的函数,如果再不同文件中都要使用,就只能复制粘贴,又出现了重复代码
问题:
1.如何拆分文件
2.拆分后怎么使用别的文件中的内容
上述问题的解决方案就是拆分模块
什么是模块
模块就是一堆功能的集合体,以py文件的形式存在
简单的就是具备一堆函数的py文件
模块的分类
1.自定义模块(重点学习),包含第三方模块(学习用法即可)
2.内置模块,例如time,os(主要学怎么使用)
3.经过编译后的C或C++库,以DLL形式存在(忽略)
4.包(本质就是一个文件夹,其中包含了一堆模块)
import 用于导入一个模块
会立即执行模块中的代码
导入模块时发生了什么:
1.创建了一个名称空间
2.执行模块中的代码,将内部的名称与值的对应关系存储到名称空间中
3.在当前执行文件创建一个名字,该名字指向被导入模块的名称空间
注意:模块之间的名称空间是相互独立的
模块中的代码仅在第一次被导入的时候执行一次
pycharm会自动帮你检测,项目根目录下的模块
可以给你一些提示,但是对于不在根目录下的,它可能会报错
这是pycharm的问题,不影响执行
使用from导入时会把import后的名字直接放入当前名称空间
使用时可以不要写前缀
注意:可能会与当前名称空间中的名字冲突
如果真的冲突了会就近查找,谁最后定义就找谁
as是区别名
from 文件名 import 函数名 是可以一次性导入多个
*是通配符 会将模块中所有名字全部导入
极容易出现名称冲突,要慎用
__all__是指定特殊变量,用于指定哪些名字可以被*导入
__name__属性可以获取当前这个模块的名字
当这个文件作为执行文件被执行时,__name__的值是__main__
当这个文件被导入执行时,__name__的值是模块的名字
模块搜索路径
使用模块时必须先找到对应的模块文件,这就涉及到搜索路径
1.查找内存中已存在的(用import sys可以看哪些模块已在内存中加载)
2.内置的
3.sys.path
当你要使用的模块不在执行文件同一级下时,就找不到,无法使用
坑爹的是,pycharm会自动把项目根目录加入sys.path
如果碰巧要找的文件在项目根目录下,便能找到
但是如果你换了运行环境不再是pycharm,就可能找不到
为了保证项目在哪里都能运行,我们需要自己将要使用的文件路径添加到sys.path中
可以将sys.path理解为解释器的环境变量
如果你的执行文件在根目录下,就能访问到当前项目中所有文件,无需关心sys.path