Python函数的分类
Python中函数分为如下几类:
1. 内置函数 我们前面使用的str()、list()、len()等这些都是内置函数,我们可以拿来直接使用。
2. 标准库函数 我们可以通过 import 语句导入库,然后使用其中定义的函数
3. 第三方库函数 Python社区也提供了很多高质量的库。下载安装这些库后,也是通过 import 语句导 入,然后可以使用这些第三方库的函数
4. 用户自定义函数 用户自己定义的函数,显然也是开发中适应用户自身需求定义的函数。今天我们学习的 就是如何自定义函数。
函数的定义和调用
核心要点
Python中,定义函数的语法如下: def 函数名 ([参数列表]) : '''文档字符串''' 函数体/若干语句
要点:
1. 我们使用def 来定义函数,然后就是一个空格和函数名称; (1) Python执行 def时,会创建一个函数对象,并绑定到函数名变量上。
2. 参数列表 (1) 圆括号内是形式参数列表,有多个参数则使用逗号隔开
(2) 形式参数不需要声明类型,也不需要指定函数返回值类型
(3) 无参数,也必须保留空的圆括号
(4) 实参列表必须与形参列表一一对应
3. return返回值
(1) 如果函数体中包含 return语句,则结束函数执行并返回值;
(2) 如果函数体中不包含return 语句,则返回None 值。
4. 调用函数之前,必须要先定义函数,即先调用def 创建函数对象 (1) 内置函数对象会自动创建 (2) 标准库和第三方库函数,通过import 导入模块时,会执行模块中的def 语句
我们通过实际定义函数来学习函数的定义方式。
形参和实参
形参和实参的要点,请参考上一节中的总结。在此不再赘述。
【操作】定义一个函数,实现两个数的比较,并返回较大的值。
返回值
return返回值要点:
1. 如果函数体中包含return 语句,则结束函数执行并返回值;
2. 如果函数体中不包含return语句,则返回 None 值。
3. 要返回多个返回值,使用列表、元组、字典、集合将多个值“存起来”即可。
【操作】定义一个打印 n个星号的无返回值的函数
【操作】定义一个返回两个数平均值的函数
变量的作用域(全局变量和局部变量)
变量起作用的范围称为变量的作用域,不同作用域内同名变量之间互不影响。变量分为:全 局变量、局部变量。
全局变量: 1. 在函数和类定义之外声明的变量。作用域为定义的模块,从定义位置开始直到模块 结束。
2. 全局变量降低了函数的通用性和可读性。应尽量避免全局变量的使用。
3. 全局变量一般做常量使用。
4. 函数内要改变全局变量的值
,使用global声明一下 局部变量:
1. 在函数体中(包含形式参数)声明的变量。
2. 局部变量的引用比全局变量快,优先考虑使用。
3. 如果局部变量和全局变量同名,则在函数内隐藏全局变量,只使用同名的局部变量
运行结果:
耗时 2.3589999675750732
耗时 1.6410000324249268
参数的传递
函数的参数传递本质上就是:从实参到形参的赋值操作。 Python中“一切皆对象”, 所有的赋值操作都是“引用的赋值”。所以,Python中参数的传递都是“引用传递”,不 是“值传递”。具体操作时分为两类: 1. 对“可变对象”进行“写操作”,直接作用于原对象本身。 2. 对“不可变对象”进行“写操作”,会产生一个新的“对象空间”,并用新的值填 充这块空间。(起到其他语言的“值传递”效果,但不是“值传递”)
可变对象有: 字典、列表、集合、自定义的对象等 不可变对象有: 数字、字符串、元组、function等
传递可变对象的引用
传递参数是可变对象(例如:列表、字典、自定义的其他可变对象等),实际传递的还是对 象的引用。在函数体中不创建新的对象拷贝,而是可以直接修改所传递的对象。
参数传递:传递可变对象的引用 b = [10,20] def f2(m): print("m:",id(m)) #b和m是同一个对象 m.append(30) #由于 m是可变对象,不创建对象拷贝,直接修改这个对象
f2(b) print("b:",id(b)) print(b)
执行结果: m: 45765960
b: 45765960 [10, 20, 30]
传递不可变对象的引用
传递参数是不可变对象(例如:int、float、字符串、元组、布尔值),实际传递的还是对 象的引用。在”赋值操作”时,由于不可变对象无法修改,系统会新创建一个对象。 【操作】参数传递:传递不可变对象的引用 a = 100 def f1(n): print("n:",id(n)) #传递进来的是a 对象的地址 n = n+200 #由于 a是不可变对象,因此创建新的对象n print("n:",id(n)) #n已经变成了新的对象 print(n) f1(a) print("a:",id(a))
执行结果: n: 1663816464 n: 46608592 300 a: 1663816464
显然,通过id值我们可以看到 n和 a一开始是同一个对象。给 n赋值后,n是新的对象。