一、生成器表达式
这是列表生成式:
res=[i for i in range(10) if i >5] #此处为中括号
print(res)
输出结果为:
[6,7,8,9]
这是列表生成器:
g=(i for i in range(10) if i >5) #此处为小括号 #没有元组生成式
print(g)
输出结果为:
<generator object <genexpr> at 0x000001A4B0B4AAF0> #这里面一个数据也没有,只是一行表达式,保存了一段代码。不触发运行就没数据。
print(next(g)) #对生成器进行next操作
输出结果为:6
想要读取文件的字符长度:
with open('c.txt', mode='rt',encoding='utf8') as f:
res=sum(len(line) for line in f) # sum求和,括号里面是迭代器,每次只返回一个值,不占用内存。
# res=sum((len(line) for line in f)) #上句为本句的简写形式
print(res)
二、模块
模块:模块就是一系列功能的集合体
模块分为四个通用的类别:
1 使用python编写的.py文件
2 已被编译为共享库或DLL的C或C++扩展
3 把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)
4 使用C编写并链接到python解释器的内置模块
模块的三种来源:
1.内置模块
2.第三方模块
3.自定义模块 #命名是不要与内置的冲突,命名规则是纯小写和下划线
为什么要用模块:
1.使用内置或者第三方的模块的好处是拿来主义,极大地提升开发效率
2.使用自定义的模块的好处是将程序各部分组件公用的功能提取取到一个模块里,其他组件通过导入的方式使用,该模块的好处是减少代码冗余
首次导入模块会发生的三件事:
1、会产生一个模块的名称空间
2、执行模块文件的内容,将产生的名字放到模块的名称空间里
3.1在当前执行文件中拿到一个名字(模块名字),该名字指向模块的名称空间。
之后的导入直接引用首次导入的成果。(import 方法)
3.2在当前执行文件中拿到一个名字(模块中函数的名字),该名字指向模块的名称空间中的函数。
之后的导入直接引用首次导入的成果。(from xx import func1,func2方法)
名称空间与作用域在定义的时候就确定了,与引用位置无关。
模块中函数调用的参数等信息都是从模块中取得的!
简写模块名的方法:
import spam as sm #将模块名spam简化为sm
print(sm.func1()) #输出模块sm中函数func1的返回值
一次导入多个模块:
import os,sys,spam #不推荐这么写,还是一次一次导入
import方法总结:
优点:指名道姓地问某一个名称空间要名字,不会与当前执行文件名称空间中的名字冲突
缺点:引用模块中的名字必须加前缀(模块名.),不简洁
from。。。import方法总结:
优点:引用模块中的名字不用加前缀,简洁
缺点:容易与当前执行文件的名称空间中的名字冲突
import方法和from xxx import a,b,c
# 定义模块
__all__=['egon','kevin'] #如果直接用import方法被导入,此句不执行;如果是from xxx import 具体的函数名,此句也不执行;但如果from xxx import * ,导入*,则只会导入列表中存在的变量名。此句模块中不一定有。
def egon():
print('吃了么?')
def kevin():
print('吃了')
def alex():
print('好饿')
# 引用模块
from xxx import * # *代表导入模块xxx中的所有函数,但如果模块中有__all__列表,则只导入列表中的函数。
egon()
kevin()
alex() # 如果是*方法导入,则此处会报错
模块的搜索路径:
查找模块路径的优先级:
1、内存
2、内置模块
3、sys.path # 是以执行文件为准的,sys.path寻找到的第一个文件夹就是当前执行文件所在的文件夹。(如果无法导入,问题可能是要导入的模块不在当前执行文件所在的文件夹。(问题出在前三排,根子就在主席台))
被导入的模块,参考的都是执行文件的sys.path (也就是说被导入模块中如果又引用了其他模块,要判断是否有问题)
环境变量的处理:
添加模块所在路径:
import sys
sys.path.append(r'C:UserswangtPycharmProjects
ewzz') #此处填写模块所在文件夹的路径,然后再导入模块即可。
import spam #模块spam即在上述路径中
也可以使用:
from zz import spam #要求文件夹zz与当前执行文件平级,即文件夹zz与当前执行文件都在同一个大文件夹中
三、如何区分py文件的两种用途
在文件内执行:
print(__name__)
当文件被当做执行文件执行时,输出结果为__main__
当文件被当做模块导入时,输出结果为__模块名__ (即py文件名)
四、软件开发的目录规范
先建立一个大的文件夹,下面建立子文件夹。
bin:start 启动文件,也就是执行文件(环境变量以此为准)
conf: settings 配置文件
core:src 写核心逻辑
lib:自定义模块
db:数据相关文件
log:transtion.log 日志文件
readme:介绍性内容
1、应该把项目的根目录加到环境变量里
2、应该把项目根目录所在绝对路径拿到,然后加到环境变量里
import os
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #获得当前文件所在的文件目录(此处向上推了两层)
sys.path.append(BASE_DIR) #添加到环境变量中
但是如果将start文件直接放到软件的根目录下,就可以省掉很多步骤:
将启动文件直接放到软件的根目录下:
from core import scr #这种结构即可
项目名直接建在pycharm的顶级目录,可以使用pycharm的提醒与补全功能。(pycharm只能识别到顶级文件夹下的子文件夹的子文件夹)