目录
三十四、函数进阶
1、函数的多返回值
一个函数要有多个返回值,按照返回值的顺序,写对应顺序的多个变量接收即可,变量之间用逗号隔开,支持不同类型的数据return
#演示使用多个变量,接收多个返回值
def test_return():
return 1,"ikun",True
x,y,z=test_return()
print(x) # 结果:1
print(y) # 结果:ikun
print(z) # 结果:True
2、函数参数种类
使用方式上的不同,函数有4中常见参数使用方式:
位置参数;关键字参数;缺省参数;不定长参数
①、位置参数:
调用函数时根据函数定义的参数位置来传递参数
def user_info(name, age, gender):
print(f"您的名字是{name},年龄是{age},性别是{gender}")
user_info('ikun',2.5,'man')
# 输出结果为:您的名字是ikun,年龄是2.5,性别是man
注意:传递的参数和定义的参数的顺序及个数必须一致
②、关键字参数:
函数调用时通过“键=值”形式传递参数
作用:可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求
def user_info(name, age, gender):
print(f"您的名字是{name},年龄是{age},性别是{gender}")
# 关键字传参
user_info(name='ikun',age=2.5,gender='man')
# 可以不按照固定顺序
user_info(age=2.5,gender='man',name='ikun')
# 可以和位置参数混用,位置参数必须在前,且匹配参数顺序
user_info('ikun',age=2.5,gender='man')
# 上述的输出均是:您的名字是ikun,年龄是2.5,性别是man
注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,蛋关键字参数之间不存在先后顺序
③、缺省参数:
缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)
作用:当调用函数时没有传递参数,就会使用默认是用缺省参数对应的值
def user_info(name, age, gender='man'):
print(f"您的名字是{name},年龄是{age},性别是{gender}")
user_info('ikun',2.5) # 您的名字是ikun,年龄是2.5,性别是man
user_info('geigei',2.5,'woman') # 结果:您的名字是geigei,年龄是2.5,性别是woman
注意:函数调用时,如果为缺省参数传值则修改默认参数值,否则使用这个默认值
④、不定长参数:
不定长参数也叫可变参数,用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。
作用:当调用函数时不确定参数个数时,可以使用不定长参数
不当初参数有2个类型:位置传递和关键字传递
关键字传递:
def user_info(**kwargs):
print(kwargs)
user_info(name='ikun',age=2.5,id=666) # 结果为:{'name':'ikun','age':2.5,'id':666}
注意:参数是”键=值“形式的形式的情况下,所有的”键=值“都会被kwargs接收,同时会根据”键=值“组成字典。
位置传递:
def user_info(*args):
print(args)
user_info('ikun') # 结果为:('ikun',)
user_info('ikun',2.5) # 结果为:('ikun', 2.5)
注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是位置传递
⑤、小结
1.掌握位置参数
根据参数位置来传递参数
2.掌握关键字参数
通过“键=值”形式传递参数,可以不限参数顺序
可以和位置参数混用,位置参数需在前
3.掌握缺省参数
不传递参数值时会使用默认的参数值
默认值的参数必须定义在最后
4.掌握不定长参数
位置不定长传递以*号标记一个形式参数,以元组的形式接受参数,形式参数一般命名为args
关键字不定长传递以**号标记一个形式参数,以字典的形式接受参数,形式参数一般命名为kwargs
3、lamdba匿名函数
函数的定义中:
def关键字,可以定义带有名称的函数
lambda关键字,可以定义匿名函数(无名称)
有名称的函数,可以基于名称重复使用
无名称的匿名函数,只可临时使用一次
语法:
lambda 传入参数:函数体(一行代码)
lambda 是关键字,表示定义匿名函数
传入参数表示匿名函数的形式参数,如:×,y表示接收2个形式参数
函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
#定义一个函数,接受其它函数输入
def test_func(compute):
result = compute(1,2)
print(f"结果是:{result}")
# 通过Lambda匿名函数的形式,将匿名函数作为参数传入
test_func(lambda x, y: x + y)
注意:使用def和使用lambda,定义的函数功能完全一致,只是lambda关键字定义的函数是匿名的,无法二次使用
三十五、文件
1、文件的编码:
编码技术即:翻译的规则,记录了如何将内容翻译成二进制,以及如何将二进制翻译回可识别内容
计算机中有许多可用编码:
UTF-8;GBK;Big5;等等
不同的编码,将内容翻译成二进制也是不同的。如果用了错误的编码,可能会导致乱码
注意:UTF-8是目前全球通用的编码格式,除非有特殊需求,否则,一律以UTF-8格式进行文件编码即可。
2、文件的读取操作:
首先我们先要知道什么是文件:
内存中存放的数据在计算机关机后就会消失。要长久保存数据,就要使用硬盘、光盘、U盘等设备。为了便于数据的管理和检索,引入了“文件”的概念。
一篇文章、一段视频、一个可执行程序,都可以被保存为一个文件,并赋予一个文件名。操作系统以文件为单位管理磁盘中的数据。一般来说,文件可分为文本文件、视频文件、音频文件、图像文件、可执行文件等多种类别。
在日常生活中,文件操作主要包括:打开、关闭、读、写等操作。
①open()打开函数
在python,使用open函数,可以打开一个以及存在的文件,或者创建一个新文件,语法如下“
open(name,mode,encoding)
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
mode:设置打开文件的模式(访问模式):只读、写入、追加等。
encoding:编码格式(推荐使用utf-8)
f = open('python.txt', 'r', encoding=" UTF-8 ")
#encoding的顺序不是第三位,所以不能用位置参数,用关键字参数直接指定
注意:此时的‘f’是‘open’函数的文件对象,对象会在后续的内容中更新
模式 | 描述 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,原有内容会被删除。 如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,新的内容将会被写入到已有内容之后。 如果该文件不存在,创建新文件进行写入。 |
②read()读操作
语法:
文件对象.read(num)
num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据。
③readlines()读操作
语法:
文件对象.readlines()
readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素
④readline()读操作
语法:
文件对象.readline()
readline对比于readlines的区别在于:一次读取一行内容
⑤for循环读取文件行
语法: for 临时变量 in open(name,mode):
输出内容
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
mode:设置打开文件的模式(访问模式):只读、写入、追加等。
for line in open("python.text","r"):
print(line)
# 每一个line临时变量,就记录了文件的一行数据
⑥close()关闭文件对象
语法:
文件对象.close()
最后通过close,关闭文件对象,也就是关闭对文件的占用
如果不调用close,同时程序没有停止运行,那么这个文件将一直被python程序占用。
⑦with open 语法
with open(“python.txt”,“r”)as f :
f.readlines()
通过在with open 的语句块中对文件进行操作
可以在操作完成后自动关闭close文件,避免遗忘close方法
⑧小结
操作 | 功能 |
文件对象 = open(file, mode, encoding) | 打开文件获得文件对象 |
文件对象.read(num) | 读取指定长度字节,不指定num读取文件全部 |
文件对象.readline() | 读取一行 |
文件对象.readlines() | 读取全部行,得到列表 |
for line in 文件对象 | for循环文件行,一次循环得到一行数据 |
文件对象.close() | 关闭文件对象 |
with open() as f | 通过with open语法打开文件,可以自动关闭 |
3、文件的写出操作
①、open函数的“w”模式进行写入
write(),写入内容
flush(),刷新内容到硬盘中
# 打开文件
f = open("ikun.txt", 'w', encoding='utf-8')
# 文件写入
f.write("geigei")
# 内容刷新
f.flush()
# 文件关闭
f.close()
注意:直接调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区
当调用flush的时候,内容会真正写入文件
这样做是避免频繁的操作硬盘,导致效率下降(攒一陀,一次解决)
还有需要注意的有:w模式当文件不存在时,会创建新文件,当文件存在时,会清空原有内容,close()方法中自带flush()方法的功能,也就是你关闭文件会自动刷新。
②、open函数的“a”模式进行写入
方法:与w模式一致
# 打开文件
f = open("ikun.txt", 'a', encoding='utf-8')
# 文件写入
f.write("2.5")
# 内容刷新
f.flush()
# 文件关闭
f.close()
注意:a模式当文件不存在时会创建文件,当文件存在时,会在最后追加写入文件,添加的内容适用于python中的语法,例如换行可以用“\n”来写出。
三十六、异常
1、语法:
①、基础语法
try: 可能发生错误的代码 except: 如果出现异常执行的代码 |
try :
print(name)
except:
print("出现异常啦")
②、捕获指定异常:
try :
print(name)
except NameError as e:
print("出现异常啦\n", e)
捕获异常只需要在except后面加上指定异常的类型即可。
注意:如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常
一般try下方只放一行尝试执行的代码
③、捕获多个异常:
try :
print(name)
except (NameError, ZeroDivisionError) as e:
print("出现异常啦\n", e)
当捕获多个异常时,可以把要捕获的异常类型的名字,放到except后,并使用元组的方式进行书写
④、异常的else
try :
print(name)
except (NameError, ZeroDivisionError) as e:
print("出现异常啦\n", e)
else:
print("没有异常我会执行")
else表示的是如果没有异常要执行的代码
⑤、异常的finally
try :
print(name)
except (NameError, ZeroDivisionError) as e:
print("出现异常啦\n", e)
else:
print("没有异常我会执行")
finally:
print("不管有没有异常,我都会执行")
finally表示的是无论是否异常都要执行的代码,如关闭文件
2、异常的传递
异常是具有传递性的,当函数fun1中发生异常,并没有捕获处理这个异常的时候,异常会传递到函数fun2,当fun2也没有捕获处理这个异常的时候,main函数会捕获处理这个异常,这就是异常的传递性。
其实也就是在函数调用中,只要最外层的函数存在异常处理,程序就不会报错,当所有函数都没有捕获异常的时候,程序就会报错
三十七、模块
1、定义
Python 模块(Module),是一个Python 文件,以.py结尾。模块能定义函数,类和变量,模块里也能包含可执行的代码.
模块的作用: python中有很多各种不同的模块,每一个模块都可以帮助我们快速的实现一些功能,比如实现和时间相关的功能就可以使用time模块我们可以认为一个模块就是一个工具包,每一个工具包中都有各种不同的工具供我们使用进而实现各种不同的功能.
大白话:模块就是一个Python文件,里面有类、函数、变量等,我们可以拿过来用 (导入模块去使用)
在pycharm按住ctrl点击模块名,就可以查看对应模块的详细代码了
2、模块的导入方式
模块在使用前需要导入,导入的语法如下:
[from 模块名] import [模块 | 类 | 变量 | 函数 | *] [as 别名]
[]中的内容是可以缺省的,import是一定要写的
模块的导入一般写在代码文件的开头位置
常见的组合形式:
import 模块名 from 模块名 import 类、变量、方法等 from 模块名 import * import 模块名 as 别名 from 模块名 import 功能名 as 别名 |
3、语法:
①、基本语法:
import 模块名
import 模块名1,模块名2
模块名.功能名()
#导入时间模块
import time
print('开始')
# 让程序睡眠1喵
time.sleep(1)
print('结束')
②、from 模块名 import 功能名
功能名()
from time import sleep
print('开始')
# 让程序睡觉一秒
sleep(1)
print('结束')
③、from 模块名 import *
功能名()
from time import *
print('开始')
# 让程序睡觉一秒
sleep(1)
print('结束')
注意:与直接import的区别在于调用时,不需要写模块名和“.”
④、as定义别名
#模块定义别名
import 模块名 as 别名
#功能定义别名
from 模块名 import 功能 as 别名
# 模块别名
import time as tt
tt.sleep(5)
print(123)
# 模块别名
from time import sleep as sl
sl(5)
print(123)
3、自定义模块
python中已经帮我们实现了很多的模块,不过有时候我们需要一些个性化的模块,这里可以通过自定义模块实现
每个python文件都可以当作一个模块,模块的名字就是文件的名字,也就是说定义模块必须要符合标识符命名规则
这里需要注意:当导入多个模块的时候,而且模块内有同名功能,当调用这个同名功能的时候,调用到的是后面导入模块的功能
在实际开发中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在py文件中添加一些测试,此时,无论是当前文件,还是其他导入了该模块的文件,在运行的时候都会自动执行测试代码,给我们带来了很大的困扰,python针对这个添加了变量__main__变量
def test(a,b):
print(a+b)
if __name__ == '__main__':
test(3,4)
上述代码中,如果是定义文件调用的话,__name__变量就是__main__,所以if里面的代码会执行,在其他的文件中则会错误而不执行
除了__name__变量,python还提供了__all__变量,那么__all__变量有什么作用呢?
如果一个模块文件“__all__”变量,当使用from 文件 import * 导入时,只能导入这个列表的元素。需要注意的是这个变量只针对*,当你直接导入文件的名称的时候是没有影响的。
三十八、包
从物理上看,包就是一个文件夹,在该文件夹下包含了一个_init_·py 文件,该文件夹可用于包含多个模块文件
从逻辑上看,包的本质依然是模块
包的作用:管理模块
使用方法跟模块一致,就是__all__这个变量要写在__init__.py文件中
就是因为有许多非常的第三方包,python才可以更加便捷的开发
安装第三方包——pip
打开命令符程序,在里面输入 pip install 包名称 就可以了
或者通过pycharm添加
具体的我就不细说了,如果需要具体的流程可以评论区发出或者私聊我