文章目录
- 一、程序结构
- 模块 Module
- 包 package
- 标准库模块
- 二、异常处理
- 异常:父类 Exception
- 处理:
- raise 语句
- 三、迭代
- 可迭代对象 iterable
- 迭代器对象 iterator
- yield 关键字
- 五、生成器 generator
- 内置生成器:
- 生成器函数:
- 生成器表达式:
- 六、函数式编程:
- 函数作为参数:
- lambda表达式(匿名函数):
- 外部嵌套作用域:Enclosing
- 函数作为返回值:
- 闭包:
- 装饰器 decorator:拦截原函数,使其功能更强大
- 七、python语言基础 (总结) :
- 内存管理机制:
- 对象池:
- 函数参数:
- 实际参数:调用函数时
- 形式参数:创建函数时
- 面向对象:OOA(分析)、OOD(设计)、OOP(编程)
- python核心
- 八、IO
- 文件
- 字节串 (bytes)
- 文件读写
- 九、网络编程基础
一、程序结构
-
模块 Module
-
定义:包含一系列的数据、函数、类的文件,通常以.py结尾;
-
作用:让一些相关的数据,函数,类有逻辑的组织在一起,是逻辑结构更加清晰。利于多人合作开发;
-
导入:可以跨模块访问类,本质是创建变量接收其他的模块/模块中的成员。
- 方式一:直接导入整个模块,使用模块名/别名调用成员;
- import 模块名( as 别名)
- 方式二:导入部分类、方法或变量到当前作用域中,直接使用导入的成员;
- from 模块名 import 方法名/变量名( as 别名)
- 方式三:导入模块的所有成员,需注意是否与自身成员冲突;
- from 模块名 import * ( as 别名)
- 方式一:直接导入整个模块,使用模块名/别名调用成员;
-
模块变量:
-
__all__
变量:定义可导出成员,仅对 from 模块 import * 语句有效; -
__doc__
变量:文档字符串,注释; -
__file__
变量:模块对应的文件路径名; -
__name__
变量:模块自身名字,可以判断是否为主模块;-
被导入的模块,打印的是真实的模块名字;
-
第一次运行的模块,打印的是
__main__
,是主模块;# main为程序的入口 # 如果当前模块是主模块,代码执行,否则不执行 if __name__ == "__main__":print("执行的代码")
-
-
-
加载过程:
- 在模块导入时,模块中的所有语句都会执行。
- 如果一个模块已经导入,再次导入时不会重复执行;
-
模块分类:
- 内置模块:builtins,在解析器的内部可以直接使用;
- 标准库模块:安装Python时已安装且可直接使用;
- 第三方模块:需要自己安装,通常为开源;
- 自定义模块:自己编写的模块,可作为其他人的第三方模块;
-
-
包 package
-
定义:将模块以文件夹的形式进行分组管理。
-
作用:让一些相关组织在一起,使逻辑结构更加清晰。
-
导入:
-
方式一:import 包名.模块名( as 别名)
-
方式二:from 包名.模块名 import 方法名/变量名( as 别名)
-
方式三:from 包名.模块名 import * ( as 别名)
-
注意:如果导入的是一个包,那么需要在包的
__init__.py
模块中设置__all__
属性;__init__.py # 设置导入的内容__all__ = ["Student"]from com.it.package import *Student.fun01() Student.Student(23).fun02()
-
-
__init__.py
的作用:
- 包内必须存在的文件,象征当前文件夹是一个包;
- 导入的时候会自动调用执行
__init__.py
模块
-
搜索顺序:内置模块 sys
- 导入模块成功的唯一条件:
- sys.path + 导入路径 可以正确定位模块的位置;
- 导入模块成功的唯一条件:
-
-
-
标准库模块
- time 时间:
- time.time():当前时间戳,1970年1月1日到现在经过的秒数;
- time.localtime():时间元组,年月日时分秒,星期,年的天数,夏令时偏移量;
- time.localtime(时间戳):接收时间戳的参数,可以将时间戳转变为一个时间元组;
- time.mktime(时间元组):可以将一个时间元组转变为一个时间戳;
- time.strftime(“%Y年%m月%d日”, 时间元组):按指定规则,格式化时间元组;
- time.strptime(时间字符串, “%Y年%m月%d日”):按指定规则,转换为时间元组;
- time 时间:
二、异常处理
-
异常:父类 Exception
- 定义:运行时检测到的错误;
- 现象:当异常发生时,程序不会继续运行,而是转到函数的调用语句;
- 常见的异常类型:
- NameError:名称异常,变量未定义;
- TypeError:类型异常,不同类型的数据进行运算;
- IndexError:索引异常,索引超出范围;
- AttributeError:属性异常,对象没有对应名称的属性;
- KeyError:没有对应名称的键;
- NotImplementedError:未实现异常,尚未实现的方法;
-
处理:
-
作用:将程序由异常状态转为正常流程;
-
统一处理:except 可以接收一个异常对象,使用 as 起别名,可调用异常的内部方法;
def calculate():try:10 / int(input("请输入整数:"))except:print("出错了")def calculate2():try:10 / int(input("请输入整数:"))except Exception as e: # 起别名print(e.args[0])
-
except语句,针对不同的错误,做相应的处理:
def calculate():try:10 / int(input("请输入整数:"))except ValueError:print("输入的不是整数")except ZeroDivisionError:print("不能除零")
-
else语句,配合expect使用,没错误时执行:
def calculate():try:10 / int(input("请输入整数:"))except ValueError:print("输入的不是整数")else:print("没有错误时执行,搭配except使用,不能单独存在")
-
finally语句:
def calculate():try:10 / int(input("请输入整数:"))except ValueError:print("输入的不是整数")finally:print("一定会执行的语句")
-
-
raise 语句
- 作用:主动抛出异常,让程序进入异常状态;
- 目的:人为抛出异常,快速传递错误信息,比层层 return 速度要快;
- 格式:raise Exception(“错误信息”)
- 自定义异常类:继承Exception类,封装异常的数据;
三、迭代
每一次对过程的重复称为一次迭代,每一次迭代的结果将会作为下一次迭代的初始值;
注:for循环一次,计算一个,返回一个;所有不会撑爆内存。
-
可迭代对象 iterable
for循环原理:可迭代对象具有
__iter__()
方法;__iter__()
:获取迭代器对象,可迭代对象 (集合、元组等) 调用;__next__()
:获取下一个元素,迭代器对象 (iterator) 调用;
iterator = list01.__iter__()while True:try:print(iterator.__next__())except StopIteration:break
-
迭代器对象 iterator
iterator:可迭代对象具有
__iter__()
方法,为迭代对象计数,长度大于可迭代对象停止迭代; -
yield 关键字
-
程序执行过程:
-
调用
__iter__()
程序不执行; -
调用
__next__()
才会执行; -
执行至 yield 暂时离开;
-
再次调用
__next__()
继续执行离开时的后续代码;
-
-
执行原理:
- 程序将 yield 前面的代码定义到next方法中;
- 程序将 yield 后面的代码作为next的返回值;
- yield 不会停止代码的执行,故 yield 后面的代码也执行;
class MyRange2:def __init__(self, data):self.__data = datadef __iter__(self):begin = 0while self.__data > begin:yield beginbegin += 1for item in MyRange2(5):print(item)
-
五、生成器 generator
-
定义:能够动态(循环一次)提供数据的可迭代对象;
-
作用:循环过程中,根据某种算法推算数据,从而节省内存空间。数据量越大越明显;
-
以上作用也称为 延迟操作 / 惰性操作,通俗的讲就是在需要的时候才计算结果,而不是一次性计算出所有结果;
-
内置生成器:
- 枚举函数 enumerate():
- 语法:
- for 变量 in enumerate(可迭代对象)
- for 索引,元素 in enumerate(可迭代对象)
- 作用:遍历可迭代对象时,可以将索引和元素组合为一个元组;
- 语法:
- 压缩函数 zip():
- 语法:
- for 变量 in zip(可迭代对象1,可迭代对象2)
- for 索引,元素 in zip(可迭代对象,可迭代对象2)
- 语法:
- 枚举函数 enumerate():
-
生成器函数:
-
定义:含有 yield 关键字的语句的函数,返回值为生成器对象;
-
语法:
-
创建:
__iter__()
函数,内部加入 yield 关键字def get_list(): # 生成新列表,每项比原列表的值大10for item in list01:yield item +10
-
调用:for循环语句自动调用
-
-
-
生成器表达式:
-
语法:
-
格式一:变量 = ( yield 返回值 for元素 in 可迭代对象)
-
格式二:变量 = ( yield 返回值 for元素 in 可迭代对象 if条件)
generate01 = (item +10 for item in list01)for item in generate01:print(item)
-
-
惰性操作:
- 优点:节省内存;
- 缺点:不能灵活访问每一项,无法使用索引、切片操作;
-
立即操作:
- 优点:灵活访问每一项,可以使用索引、切片操作;
- 缺点:占用内存;
-
惰性操作 ==> 立即操作:
- 将生成器结果转换为容器(列表、元组、集合等)
- 例如:list01 = list(item +10 for item in list01)
-
六、函数式编程:
-
定义:用一系列函数解决问题。
-
理论支柱:
- 函数可以赋值给变量,复制后变量绑定函数;
- 允许将函数作为参数传入另一个函数;
- 允许函数返回另一个函数;
-
高阶函数:将函数作为参数或返回值的函数。
- 内置高阶函数:
- map(函数,可迭代对象):根据可迭代对象,根据每一项映射出新的可迭代对象;
- filter(函数,可迭代对象):过滤出符合条件的元素;
- sorted(可迭代对象, key = 函数,reverse = 布尔值):排序,无需通过返回值传递结果
- max(可迭代对象, key = 函数):最大值
- min(可迭代对象, key = 函数):最小值
-
函数作为参数:
- 传入时不能带括号,否则直接会执行,而是将函数名传入,这样即可在方法内部再执行;
-
lambda表达式(匿名函数):
- 格式:lambda 参数:方法体,例如:
lambda num:num == 0
; - 作用:
- 作为实参传递给函数,语法简洁优雅,可读性高;
- 调用完毕立即销毁,减少代码耦合度;
- 注意:
- 若无形参可不填;
- 不能进行赋值操作;
- 方法体只支持一行语句;
- 变体:
- 单个参数:
lambda a: a==0
- 多个参数:
lambda a, b, c: a==b==c
- 没有参数:
lambda : '无参数'
- 没参数,没返回值:
lambda a: print('无返回值')
- 单个参数:
- 格式:lambda 参数:方法体,例如:
-
外部嵌套作用域:Enclosing
def fun01():a = 10 # 局部变量,外部嵌套变量def fun02():b = 20 # 局部变量print(a) # 此时可读取外部嵌套变量,却不能修改nonlocal a # 使用nonlocal声明外部嵌套变量后,才可修改,与global类似a = 20 # 修改外部嵌套变量
-
函数作为返回值:
逻辑连续,当内部函数被调用时,不脱离当前的逻辑;
-
闭包:
-
闭包说明:
- 非嵌套函数:调用时,在内存中开辟栈帧;函数执行完毕,栈帧释放,局部变量销毁;
- 嵌套函数:外部函数执行完毕后,不会释放栈帧,销毁局部变量;而是留给内部函数继续使用;
-
三要素:
- 必须有一个内嵌函数;
- 内嵌函数必须引用外部函数中的变量;
- 外部函数返回值必须是内嵌函数;
-
语法:
def 外部函数名(参数):外部变量def 内部函数名(参数):nonlocal 外部变量 # 声明外部函数,而不是新创建一个使用外部变量
-
优缺点:
- 优点:内部函数可以使用外部函数;
- 缺点:外部变量会一直存在于内存中;
-
作用:为了实现函数装饰器;
-
应用:
def fun01(money):def fun02(num):nonlocal moneyif money > num:money -= numprint("余额:", money)else:print("余额不足")return fun02 # 返回值为一个函数fun03 = fun01(1000) # 调用函数1,返回值为一个函数fun03 fun03(200) # 调用返回的函数,这时,局部变量不会销毁 fun03(400) # 调用返回的函数 fun03(500) # 调用返回的函数
-
-
装饰器 decorator:拦截原函数,使其功能更强大
-
定义:在不改变原函数的调用以及内部代码的情况下,为其添加新的功能;
-
语法:
def 装饰器名称(func):def 内嵌函数名称(*args, **kwargs):'需要添加的新功能'return func(*args, **kwargs)return 内嵌函数名称# 调用 原函数上添加注解:@装饰器名称
-
例如:
def add_name_to_say(func): # 装饰器方法def wrapper(*args, **kwargs):print(func.__name__)return func(*args, **kwargs)return wrapper@add_name_to_say # 调用装饰器 def say_hello():print("hello")@add_name_to_say def say_goodbye():print("goodbye")say_hello() say_goodbye()
-
-
七、python语言基础 (总结) :
-
内存管理机制:
-
引用计数:
-
每个变量存储对象地址时,引用计数都会自增1;
-
每个变量与对象引用断开时,引用计数都会自减1;
-
如果引用计数为0,对象则被释放;
- 缺点:解决方式:标记清除
- 循环引用:垃圾引用垃圾,导致无法释放内存;
-
-
标记清除:扫描内存,查看是否存在无法访问的内存空间;
- 缺点:耗时长,解决方式:分代回收
-
分代回收:每代的内存告急时,采用标记清除,将有用的数据升至下一代;
- 新生代:存储数据时开辟空间;
- 中年代:新生代满时,将有用的数据存放至此;
- 老年代:中年代满时,将有用的数据存放至此;
-
内存优化:
- 尽少的产生内存垃圾;
- 对象池
- 手动回收:慎用!
-
-
对象池:
- 每次创建对象时,都会判断池中是否具有相同的对象;有,拿来用。没有,创建;
- 优点:提高内存的利用率;
-
函数参数:
-
面向对象:OOA(分析)、OOD(设计)、OOP(编程)
- 软件项目生命周期:
- 前期 -> 市场:招标、投标
- 中期 -> 开发:
- 项目启动 --> 项目立项报告
- 需求调研 --> 需求规格说明书、需求分析说明书
- 设计开发 -->
- 概要设计:架构、系统功能设计、关键类、关键算法
- 详细设计:子类、类成员、数据、业务细节
- 编码:
- 整体测试 --> 功能、性能
- 试运行
- 项目验收
- 后期 -> 服务:运维
- 软件项目生命周期:
-
python核心
- 迭代器 --> 生成器(惰性/延迟)
- 函数式编程:
- 函数作为参数:将核心逻辑传入函数
- 函数作为返回值:闭包 --> 装饰器
- 不改变原有功能,在原基础上增加性能
- 装饰器:
- 核心思想:拦截旧功能
- 新功能与旧功能包装在一起
八、IO
-
定义:数据流的输入输出,在内存中进行数据交换的操作,一般认为是IO操作;
-
程序分类:
- IO密集型程序:IO操作较多;
- 计算密集型程序:计算操作较多;
-
文件
- 格式编码角度分为:文本文件、二进制文件
- python中把文件视为一种类型的对象;
-
字节串 (bytes)
- python3中引入字节串的概念;
- 字节串以字节序列值表达数据,更方便处理二进制数据;
- 格式:
b'字符串'
,仅支持ASCII,例如:s = b'abc'
; - 格式:
b'字符串'.encode()
,encode() 将字符串(str)转换 字节串(bytes),decode()反之;
-
文件读写
-
对文件读写的基本操作:打开文件、读写文件、关闭文件。
- 打开文件:
open(file_name, access_mode='r', buffering=-1)
,返回一个文件操作对象;- 参数一:file_name,文件名称;
- 参数二:access_mode,打开文件的方式,默认为 ‘r’ ;
- r:以读的方式打开,文件必须存在。
- w:以写的方式打开,无法获取文件内容。文件不存在则创建;文件存在则清空文件内容。
- a:以追加模式打开,不会清空文件内容,而是在后面继续写。
- r+:以读写模式打开,文件必须存在。
- w+:以读写模式打开。
- a+:以读写模式打开,追加模式。
- rb:以二进制读模式打开,同r。
- wb:以二进制写模式打开,同w。
- ab:以二进制追加模式打开,同a。
- rb+:以二进制读写模式打开,同r+。
- wb+:以二进制读写模式打开,同w+。
- ab+:以二进制读写追加模式打开,同a+。
- 参数三:buffering,默认-1,使用系统默认的缓冲机制;1 指行缓冲。
- 缓冲区刷新条件:
- 缓冲区被写满;
- 程序执行结束,或文件对象被关闭;
- 行缓冲遇到换行符( “\n” );
- 主动调用 flush() 函数;
- 缓冲区刷新条件:
- 打开文件:
-
说明:
- 文本文件:可以用文本或二进制方式打开;
- 二进制文件:必须使用二进制方式打开;
-
文件的操作:
-
打开文件:
file01 = open('file/test.txt', 'r') # 只读,文件必须存在 file01 = open('file/test.txt', 'w') # 只写,不存在则创建 file01 = open('file/test.txt', 'a') # 追加,append
-
读写操作:
# 写入文件, 区别writelines(),writelines()可以写入多行,write()只能写入一行 file01.write(str01) file01.writelines(str01)# 读取文件 print(file01.read(5)) # 读取5个字符, 不包括换行符, 不给参数默认读取全部 print(file01.readline()) # 读取一行,换行符也读取,但是不会返回换行符,只返回一行,如果要返回换行符,可以使用readlines() print(file01.readlines()) # 读取所有行,返回一个列表,每一行作为一个元素# 迭代特性 for line in file01:print(line) # 一次读取一行
-
关闭文件:
file01 = open('file/新建文本文档.txt', 'r') file01.close() # 关闭资源
-
with语句块:(语句块结束,文件则自动销毁,无需调用close方法)
# 等价于 f = open('file/test.txt', 'r') with open('file/test.txt', 'r') as f:data = f.read()print(data)
-
文件拷贝:
rf = open('C:/Users/范亚鑫/Desktop/20000000.xlsx', 'rb') wf = open('C:/Users/范亚鑫/Desktop/40000000.xlsx', 'wb')while True:line = rf.read(1024)if not line:breakwf.write(line)rf.close() wf.close()
-
-
文件偏移量:
- 定义:对文件进行操作时,系统会自动生成一条记录,记录了对文件的一系列操作,例如读写的位置,下次操作会自动从记录的位置进行操作。
- 注意:
- 读和写用的是同一个偏移量;
- 每次调用open函数时,偏移量都将刷新,r / w 偏移量处于文件开头,a 偏移量处于末尾;
- 基本操作:
- tell() 函数:获取当前的偏移量大小;
- seek(offset, whence) 函数:更改文件偏移量的位置;whence必须二进制可选 1 / 2;
- offset:正数向后偏移,负数向前偏移
- whence:可省,默认0;0指文件开头算起;1指当前位置开始,2指文件末尾算起;
- 空洞文件:指文件内容很小,却占用了很大空间,用于占用内存,为后续操作做准备;
-
文件描述符:
- 定义:系统中每一个IO操作都会分配一个整数编号,这个编号就是文件描述符;
- fileno() 函数:获取文件描述符;
-
文件管理函数:os模块
- os.path.getsize():获取文件大小;
- os.listdir(‘path’):path为目录名,获取目录内的文件列表;
- os.path.exists():判断文件是否存在;
- os.path.isfile(‘filename’):filename为文件名,判断文件是否为普通文件;
- os.remove(‘filename’):filename为文件名,删除文件
-
九、网络编程基础
未完待续…