第四章:Python之函数
off999 2024-11-21 19:25 26 浏览 0 评论
第一节:函数入门与定义函数
- 理解函数
- 所谓函数,就是为一段实现特定功能的代码“取”个名字,以后即可通过该名字来执行(调用)这段代码
- 从逻辑上看,函数相当于一个黑匣子
- 定义函数的语法
- 定义函数的三条铁律
- 函数需要几个关键的、需要动态变换的数据,这些数据就应该定义成函数的参数
- 函数需要传出去几个重要的数据(就是调用该函数的人希望得到的数据),这些数据应该定义成返回值
- 函数内部的实现过程
- 函数的语法:
# 定义函数,无参数
def first():
# 之前学习的定义变量、赋值、运算、分支、循环等全部都可以写在函数里面
print('first 函数')
for i in range(5):
print(i)
first()
# 只要执行函数,函数体的代码就可以被重复的调用(复用)
first()
first()
# 函数定义,有一个参数 name
def hello(name):
print('hello 函数')
print('您好,' + name)
hello('python')
hello('java')
# 函数定义,有2个参数 name, age
def info(name, age):
print('info函数')
print('name参数', name)
print('age参数', age)
info(python, 90)
info(java, 70)
# 定义函数,有返回值
def max(a, b):
r = a if a > b else b
# 返回值
return r
# 返回值的意思,当程序调用函数之后,会得到N个值
x = max(10, 20)
print(x)
x = max(30, 20)
print(x)
# print也是个函数,函数的嵌套
print(max(20, 50))- 为函数提供文档
- 只要把一段字符串放在函数声明之后、函数体之前,这段字符串就是函数的说明文档
- Python内置的help()函数查看其它函数的帮助文档
- 通过函数的_doc_属性来查看函数的说明文档
# 自定义说明文档
def test(a):
'''
test 函数的说明,这是一个简单的函数
a-代表什么意义
return- 代表什么意义
'''
# 空语句
pass
print(test.__doc__)
help(test)第二节:多返回值函数与递归函数
- 多返回函数
- 多返回值,本质就是返回元组
- 程序即可返回元组,也可直接返回多个值(系统会自动将其封装成元组)
- 获取多返回值函数的返回值时
- 既可以用单个变量(元组)来获取
- 也可以用多个变量获取(元组解包)
import random
# 希望该函数返回三个随机的大写字符
def test():
# 生成三个随机的大写字符
c1 = chr(random.randint(65,90))
c2 = chr(random.randint(65,90))
c3 = chr(random.randint(65,90))
# 以元组的形式返回
return(c1, c2, c3)
# 程序自动封装成元组
return c1, c2, c3
# r就是一个元组
r = test()
print(r)
print(test())
# 多返回值函数,即可用多个变量来接收返回值,也可用单独变量来接收返回值
c1, c2, c3 = test()
print(c1)
print(c2)
print(c3)- 递归函数
- 函数体内调用它自身,被称为函数的递归
- 函数递归包含了一种隐式的循环,它会重复执行某段代码,但是这种重复执行无需循环控制
- 递归函数的注意点
- 向已知的方向递归
- 让递归有结束的时候,不要无限递归
# 无限递归的例子
def foo():
print('111')
print('222')
foo()
foo()
# 计算N的阶乘
def frac(n):
if n < 1:
print("n不能小于1")
return
elif n == 1:
return 1
else:
# n的阶乘总是等于上一个阶乘*n
# 函数调用自身
return frac(n-1) * n
# 该函数的结束点是n==1,因此要向n==1方向递归
print(frac(5))
print(frac(6))第三节:关键字参数与参数默认值
- 关键字参数
- Python函数的参数名不是无意义的,Python允许调用函数时通过名字来传入参数值
- 调用函数时支持两种方式为参数指定值
- 位置参数:必须按照顺序为每个参数指定参数值
- 关键字参数(命名参数):按参数名为参数指定参数值
def info(name, age, height):
print("name:", name)
print("age:", age)
print("height:", height)
# 位置参数,按照顺序传递参数
info('fkjava', 24, 183)
# 关键字参数(命名参数)
# 关键字参数的优势是 1:不需要按照顺序 2:可读性更高
info(age=34, name='java', height=179)
# 混合使用
info('python', height=178, age=45)
# 混合使用错误:关键字参数必须位于位置参数的后面
info(name='python', 178, 45)- 参数的默认值
- 程序需要在定义函数的时候为一个或者多个形参指定默认值,这样调用函数时就可以省略该形参传入参数值,而是直接使用该形参的默认值
- 为形参指定默认值的语法格式如下:形参名 = 默认值
# 定义带默认值的参数(一个参数有默认值)
def info(age, name='python'):
print('age参数为:', age)
print('name参数为:', name)
# 为参数指定默认值之后,调用时候可省略指定的参数值,该参数使用默认值
info(23)
info(45, 'abc')
info(11, 'Java')
# 混合方式
info(19, name='bcd')
# 定义带默认值的参数(两个参数有默认值)
def info(age=19, name='python'):
print('age参数为:', age)
print('name参数为:', name)
info()
info(20)
# 如果你希望省略前面的参数指定参数值,后面的参数应该用关键字参数来传入参数
info(name='go')第四节:参数搜集和逆向参数收集
- 参数收集
- 普通参数收集
- 在形参前面加上一个星号(*),这样就意味着该参数可接收多个参数值,多个参数值被当成元组传入
- 参数收集的本质就是一个元组:Python会将传给带*参数的多个值收集成一个元组
- Python允许个数可变的参数可以处于形参列表的任意位置,但是最多只能带一个支持“普通”参数收集的参数
- 如果支持“普通”参数收集的形参位于前面,后面参数则需要使用关键字参数传值
# books参数支持收集,它可接受多个参数值
def test(num, *books):
print("num:", num)
print("books:", books)
# 将多个值自动封装成一个元组
test(5, "go", "python", "java")
def info(*names, msg):
for name in names:
print("%s, %s" % (name, msg))
# 如果你要为参数收集后的参数传入参数值,需要用关键字参数
info("孙悟空", "猪八戒", "牛魔王", msg="欢迎大家")
# 否则所有参数都会被参数收集成元组
info("孙悟空", "猪八戒", "牛魔王", "欢迎大家")- 关键字参数收集
- 在参数前面添加两个星号“**”,该参数支持关键字参数收集,收集的参数被当做dict处理
- 一个函数可同时支持普通参数收集和关键字参数收集
# books参数支持普通参数收集,它可接受多个参数值,socres支持关键字参数收集
def test(num, *books, **socres):
print("num:", num)
print("books:", books)
print("socres:", socres)
test(20, 'fkjava', 'python', 'swift', 语文=89, 数学=93)
def info(*names, msg, **socres):
for name in names:
print("%s, %s" % (name, msg))
print(socres)
# 程序知道msg参数将是传给msg的,因此socres参数不会收集它
# dict的参数收集,它只收集不能明确传入的关键字参数
info("孙悟空", "猪八戒", "牛魔王", msg="欢迎大家", 语文=89, 数学=93) - 逆向参数收集
- 在列表、元组前添加*,在字典之前添加**
def test(a, b):
print(a)
print(b)
# 元组的逆向参数收集,以普通参数的形式为参数传入参数值
vals = (20, 40)
# 调用函数时,元组不能自动解包
# 默认情况下,元组是一个整体
test(vals)# 这个语句是错误的
# *对元组自动解包(逆向参数收集)
test(*vals)
# 列表的逆向参数收集,以普通参数的形式为参数传入参数值
msgs = ['aa', 'bb']
test(*msgs)
# 字典的逆向参数收集,以关键字参数的形式为参数传入参数值
# 简单来说,**是将字典解析成关键字参数
vals = {'a': 89, 'b': 93}
test(**vals)第五节:变量作用域
- 理解变量作用域
- 根据定义变量的位置,变量的作用域分为两种:
- 局部变量:在函数中定义的变量包括参数,都被成为局部变量
- 全局变量:在函数外面、全局范围内定义的变量,被称为全局变量
# 全局变量
a = 35
def info():
# 局部变量
b = 'fkjava'
# 正确,局部变量只能在当前函数内访问
print(b)
# 正确,全局变量可以在任何函数内访问
print(a)
def info1():
# 局部变量
c = 'java'
print(c)
# 正确,全局变量可以在任何函数内访问
print(a)
# 错误,局部变量只能在定义局部变量的函数中使用
#print(b)
info()
info1()- 变量字典
- 获取变量字典
- globals():该函数返回全局范围内搜所有变量组成的“变量字典”
- locals():该函数返回当前局部范围内搜所有变量组成的“变量字典”
- vars(object):获取指定对象的范围内所有变量组成的“变量字典”,如果不传入object参数,vars()和locals()作用完全相同
# 全局变量
a = 35
name = 'java'
def info():
# 局部变量
b = 'fkjava'
# 正确,局部变量只能在当前函数内访问
print(b)
# 正确,全局变量可以在任何函数内访问
print(a)
# 局部变量组成的数组
print(locals())
def info1():
# 局部变量
c = 'java'
print(c)
# 正确,全局变量可以在任何函数内访问
print(a)
# 错误,局部变量只能在定义局部变量的函数中使用
#print(b)
# 局部变量组成的数组
print(locals())
# 全局变量组成的数组
print(globals())
# locals获取当前范围内的所有局部变量
# 因此你在全局范围调用locals函数的时候,它返回全部的全局变量
# 简单来说,你在全局范围内,用globals和locals函数效果是一样的
print(locals())
info()
info1()- 处理局部变量遮蔽全局变量
- 全局变量默认可以在所有函数内访问
- 如果在函数中定义了与全局变量同名的变量,此时就会发生局部变量的遮蔽(hide)全局变量的情形
# 解决方法一
name = 'java'
def info():
# 依然访问全局变量name
print(globals()['name'])
# 在函数内对变量赋值,变成了定义新的name变量
name = 'python'
print(name)
info()
# 全局变量name没有改变
print(name)
# 解决方法二
name = 'java'
def info():
# 声明作用:该函数中的name始终使用全局变量
global name
# 依然访问全局变量name
print(name)
# 前面已经声明了name始终是全局变量
# 因此此处不是重新定义局部变量
name = 'python'
print(name)
info()
# 全局变量name会被改变
print(name)第六节:局部函数
- 理解局部函数
- 放在函数体内的函数称为局部函数
- 在默认情况下,局部函数对外部是隐藏的,局部函数只能在其封闭(enclosing)函数内使用
- 定义、使用局部函数
def foo():
print('foo函数')
# 嵌套函数:在其他函数内定义的函数
def bar():
for i in range(5):
print('bar函数')
# 只能在foo函数内调用bar函数
bar()
# 在此处调用bar函数出错,局部函数只在它所在的封闭函数内有效
# bar()
foo()- 封闭函数返回局部函数
- 封闭函数可以返回局部函数,以便程序在其他作用域中使用局部函数
- 如果封闭函数没有将局部函数返回出来,那么局部函数将只能在封闭函数内部调用
def foo():
print('foo函数')
# 嵌套函数:在其他函数内定义的函数
def bar():
for i in range(5):
print('bar函数')
# bar表示返回函数本身(函数也相当于一个值,是function类型的值)
# bar()表示调用(执行)函数
return bar
# foo函数的返回值时bar函数,因此此处是用变量r来保存bar函数
r = foo()
print(r)
# 此时R引用bar函数本身,r的类型是function
print(type(r))
print('-' * 60)
# 由于r是函数,因此程序可以调用它
r()
# 下面代码看上去有点诡异
# foo函数调用之后返回bar函数,bar函数也可调用
foo()()- 局部函数的变量遮蔽
- 局部函数内的变量也会遮蔽它所在的封闭函数的局部变量
- 避免方法:可用nonlocal进行声明
def test():
name = 'fkjava'
def info():
print('info 函数')
# 声明后面的name变量不是声明新的局部变量,而是引用所在封闭函数的局部变量
nonlocal name
print('name:', name)
# 默认情况下,下面代码是为info这个局部函数再次定义name局部变量
# 此时name局部变量就会遮蔽test函数的name变量
name = 'crazyit'
# 在没有用nonlocal声明之前,此时打印会出错,用nonlocal声明之后,程序正常
print('name:', name)
info()
print(name)
test()- global与nonlocal总结
- 作用大致相同,都是用来避免变量遮蔽
- 区别:global用于声明访问全局变量。nonlocal用于声明访问局部函数所在封闭函数内的局部变量
第七节:案例实操-定义计算N的阶乘的函数
- 实现方法
- 方法一:使用循环计算阶乘
- 控制循环计数器从1循环到N
- 让循环计数器与前一个结果相乘,直到循环计数器等于N就得到了N的阶乘
def fract():
r = 1
if n < 1:
print('n不能小于1')
return
else:
for i in range(1, n + 1):
r *= i
return r
print(fract(5))- 方法二:运用递归计算阶乘
- 经研究发现:N的阶乘等于N乘以N-1的阶乘,因此可借助于递归来实现
- N为1时,N的阶乘是1,保证递归有结束点
def fract():
if n < 1:
print('n不能小于1')
return
# 对于递归函数来说,必须保证在某个条件下,函数不再调用自身,递归结束
elif n == 1:
return 1
else:
# 递归:就是函数里面调用自身
return fract(n - 1) * n
print(fract(5))- 方法三:调用reduce函数计算阶乘
- Python在functools模块提供了reduce()函数,该函数使用指定函数对序列对象进行积累
- 可通过help(reduce)查看该函数的用法:reduce(function, sequence[, initial])
import functools
def fn(x, y):
return x * y
def fract():
if n < 1:
print('n不能小于1')
return
else:
'''
# fn(ele1, ele2)->r
# fn(r,ele3)->r
# fn(r,ele4)->r
'''
# 方法一:
return functools.reduce(fn, range(1, n + 1))
# 方法二:
# lambda x ,y: x * y 的本质就是一个函数
return functools.reduce(lambda x ,y : x * y, range(1, n + 1))
print(fract(5))第八节:案例实操-定义计算矩阵转置的函数
- 使用循环进行转置
- 首先创建一个长度与原矩阵第一个元素长度相等的新列表
- 使用遍历原矩阵的每个元素,再使用嵌套循环遍历每个元素,将列表中的元素添加到新列表对应的列表元素中
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
'''
# 转置就是行变列 列变行
# 转置之前
1 2 3 4
5 6 7 8
9 10 11 12
# 转置之后
1 5 9
2 6 10
3 7 11
4 8 12
'''
def printmatrix(m):
# 列表嵌套列表,因此ele也是列表
for ele in m:
# 打印一行
for e in ele:
print('%2d' % e, end=' ')
print(' ')
def transformmatrix(m) :
# m[0]有几个元素,说明原矩阵有多少列
# 列转成行
rt = [[] for i in m[0]]
for ele in m:
for i in range(len(ele)):
# rt[i]代表新矩阵的第i行
# ele[i]代表原矩阵当前行的第i列
rt[i].append(ele[i])
return rt
printmatrix(matrix)
print('-' * 60)
printmatrix(ransformmatrix(matrix))- 使用zip()函数转置
- zip函数的作用正是合并多个序列:多个序列第一个元素合并成第一个元素,多个序列第二个元素合并成第二个元素......
- 运用逆向函数收集即可
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
def printmatrix(m):
# 列表嵌套列表,因此ele也是列表
for ele in m:
# 打印一行
for e in ele:
print('%2d' % e, end=' ')
print(' ')
def transformmatrix(m) :
# 逆向参数收集,将矩阵中多个列表转换成多个参数,传给zip
return list(zip(*m))
printmatrix(matrix)
print('-' * 60)
printmatrix(ransformmatrix(matrix))- 使用numpy模块转置
- numpy模块提供transpose函数执行转置,该函数的返回值是numpy的内置类型:array
- 调用array的tolist()方法可将array转换成list列表
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
def printmatrix(m):
# 列表嵌套列表,因此ele也是列表
for ele in m:
# 打印一行
for e in ele:
print('%2d' % e, end=' ')
print(' ')
def transformmatrix(m) :
# 使用numpy模块的transpose函数进行转置
import numpy
return numpy.transpose(m).tolist()
printmatrix(matrix)
print('-' * 60)
printmatrix(ransformmatrix(matrix))相关推荐
- 笔记本电脑选哪个品牌比较好
-
1、苹果APPLE/美国2、戴尔DELL/美国3、华为HUAWEI/中国4、小米MI/中国5、微软Microsoft/美国6、联想LENOVO/中国7、惠普HP/美国8、华硕ASUS/...
- 10系列显卡排名(10系显卡性能排行)
-
十系显卡指NVIDIAGeForce10系列,是英伟达研发并推出的图形处理器系列,被用以取代NVIDIAGeForce900系列图形处理器。新系列采用帕斯卡微架构来代替之前的麦克斯韦微架构,并...
-
- 最新win7系统下载(windows7最新版本下载)
-
最简单的方法就是,下载完镜像文件后,直接把镜像文件解压,解压到非C盘,然后在解压文件里面找到setup.exe,点击运行即可。安装系统完成后,在C盘找到一个Windows.old(好几个GB,是旧系统打包在这里,垃圾文件了)删除即可。扩展资...
-
2026-01-15 06:43 off999
- 哪个电脑管家软件好用(哪个电脑管家好用些)
-
腾讯电脑管家吧,因为这个是杀毒和管理合一的,占用内存小,因此显得更为简洁,使电脑运行更加流畅此外电脑诊所,工具箱以及4+1的杀毒模式让腾讯电脑管家也收到了广泛的关注4+1杀毒引擎,管家反病毒引擎、金山...
- 怎么进入win7安全模式(怎么进入win7安全模式界面)
-
方法如下:1、首先进入Win7系统,然后使用Win键+R组合键打开运行框,输入“Msconfig”回车进入系统配置。2、在打开的系统配置中,找到“引导”选项,然后单击,选择Win7的引导项,然后在“安...
- 怎么分区固态硬盘(怎样分区固态硬盘)
-
固态硬盘的分区方法与传统机械硬盘基本相同,以下是一个简单的步骤:1.打开磁盘管理工具:在Windows操作系统中,按下Win+X键,选择"磁盘管理"。或者打开控制面板,在"...
-
- 笔记本声卡驱动怎么下载(笔记本如何下载声卡)
-
1、在浏览器中输入并搜索,然后下载并安装。2、安装完成后打开360驱动大师,它就会自动检测你的电脑需要安装或升级的驱动。3、检测完毕后,我们可以看到我们的声卡驱动需要安装或升级,点击安装或升级,就会开始自动安装或升级声卡了。4、升级过程中会...
-
2026-01-15 05:43 off999
- win10加快开机启动速度(加快开机速度 win10)
-
一、启用快速启动功能1.按win+r键调出“运行”在输入框输入“gpedit.msc”按回车调出“组策略编辑器”?2.在“本地组策略编辑器”依次打开“计算机配置——管理模块——系统——关机”在右侧...
-
- excel的快捷键一览表(excel的快捷键一览表超全)
-
Excel快捷键大全的一些操作如下我在工作中经常使用诸如word或Excel之类的办公软件。我相信每个人都不太熟悉这些办公软件的快捷键。使用快捷键将提高办公效率,并使您的工作更加轻松快捷。。例如,在复制时,请使用CtrI+C进行复制,...
-
2026-01-15 05:03 off999
- 华硕u盘启动按f几(华硕u盘装系统按f几进入)
-
F8。1、开机的同时按F8进入BIOS。2、在Boot菜单中,置secure为disabled。3、BootListOption置为UEFI。4、在1stBootPriority中usb—HD...
- 手机云电脑怎么用(手机云端电脑)
-
使用手机云电脑,您首先需要安装相应的云电脑应用。例如,华为云电脑APP。在安装并打开应用后,您将看到一个显示器的图标,这就是您的云电脑。点击这个图标,您将被连接到一个预装有Windows操作系统和必要...
- ie11浏览器怎么安装(ie11浏览器安装步骤)
-
如果IE浏览器11版本你发现无法正常安装,那么很可能是这样几个原因,一个就是电脑的存储空间不够到时无法安装,再有就是网络的问题,如果没有办法安装的话就不要再安装了,本身这个IE浏览器并不是多好用,你最...
- 台式机重装系统win7(台式机怎么重装win7)
-
下面主要介绍两种方法以重装系统:一、U盘重装系统准备:一台正常开机的电脑和一个U盘1、百度下载“U大师”(老毛桃、大白菜也可以),把这个软件下载并安装在电脑上。2、插上U盘,选择一键制作U盘启动(制作...
- 字母下划线怎么打出来(字母下的下划线怎么去不掉)
-
第一步,在电脑上找到文字处理软件WPS,双击即自动新建一个新文档。第二步,在文档录入需要处理的字母和数字,双击鼠标或拖动鼠标选择要处理的内容。第三步,在页面的左上方的横向菜单栏,找到字母U的按纽,点击...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
python入门到脱坑 输入与输出—str()函数
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
失业程序员复习python笔记——条件与循环
-
系统u盘安装(win11系统u盘安装)
-
Python 批量卸载关联包 pip-autoremove
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
