当我们需要频繁地使用某段具备相同功能的代码块来编写项目实现代码时,有没有更为简洁的使用形式呢?这就是本文要学习的主要内容———函数
目录
一 函数基础概念
函数是Python中组织代码的一种方式,允许将代码块封装为可重复使用的单元。函数可以接受输入参数,执行特定任务,并返回结果。使用函数的主要目的是提高代码的可读性、可维护性和复用性。
二 函数定义的基本结构
- 使用
def
关键字定义函数。 - 函数名遵循变量命名规则(通常为小写字母和下划线)。
- 参数列表位于括号内,多个参数用逗号分隔。
- 函数体缩进,包含执行逻辑。
- 可选
return
语句返回结果。
三 函数的创建和调用实例
# 定义一个简单的函数
def fun(a):
a++
return a
# 调用函数
n = fun(2)+fun(3)+fun(4)
print(n) # 输出:12
上面也体现出了函数的复用特性。这样就可以节省许多
四 函数的参数
-
形参和实参
这里a,b是形参,c,d为实参
def fun(a,b):
....
return 返回值
fun(c,d)
-
位置参数
按顺序传递(如func(a, b)
)。示例代码如下
def fun(a,b):
return a+b
n=fun(2,3)
print(n)
-
默认参数
定义时赋默认值(如def func(a=1)
)。示例代码如下
def fun(a=1):
return a
print(fun())
#输出结果 1
-
可变参数
*args
接收任意数量的位置参数转换为元组。示例代码如下
def fun(a,*b):
print(a)
print(b)
return 0
fun(1,1,2,3,4)
#1
#(1, 2, 3, 4)
-
**kwargs
接收任意数量的关键字参数转化为字典。示例代码如下
def fun1(a,**b):
print(a)
print(b)
return 0
fun1(1,zhans=45,ni=55)
#输出结果
# 1
# {'zhans': 45, 'ni': 55}
五 函数的变量作用域(最清楚的讲解)
下面我分为几种情况来讲解
1 这里a作为全局变量,在fun函数中可以直接调用a的值(例如全校就一个叫小刘的,在学校叫小刘不会发生冲突)
def fun(b):
return a,b
a=1
print(fun(2))
#输出(1, 2)
2 这里a作为全局变量,在函数中对a做出赋值操作,这里函数中的a是作为局部变量,对全局变量不修改,也可以说这里函数内的a跟函数外全局变量a没关系(例如学校中有个叫小刘的,现在班级中也有一个同学小刘,那么在班级中找小刘和对小刘进行改装,对学校中的那个小刘不会有任何影响)
def fun(b):
a=2
print('函数内a',a)
a=a+1
print('函数内a',a)
a=1
fun(2)
print('函数外a',a)
输出结果:
3 这里运行会报错,原因是a=a+1,两个a会发生冲突,一个局部变量,一个全局变量会争夺变量名的使用。(例如学校中有个小刘,班级中也有个小刘,如果这个时候叫学校中的小刘进入这个班级中,那边在这个班级中找小刘会发生冲突)
def fun(b):
a=a+1
print('函数内a',a)
print('函数内b',b)
a=1
fun(3)
print('函数外a',a)
4 global声明全局变量这里在函数中对进行了全局变量的声明,且在函数中(例如,学校中有个小刘,然后在班级老师讲,班级中的小刘就是学校中的小刘,这时在班级中对小刘做任何改装都会影响学校中的小刘)
def fun(b):
global a
print('函数内a',a)
a=a+1
print('函数内a',a)
a=1
fun(3)
print('函数外a',a)
输出结果
六 可变数据
这里的是否可变是指在数据在变化时,该数据的地址会不会发生改变。其中可变数据是在改变数据时不会对地址做出变化。这里我们引入一个函数id(),来检测数据地址是否会发生变化。
1 数值型数据
a=1
print(id(a))
a=2
print(id(a))
输出结果:
则为不可变数据
2 字符型数据
a='aaa'
print(id(a))
a='abc'
print(id(a))
输出结果:
则为不可变数据
3 列表型
a=[1,2]
print(id(a))
a.append(3)
print(id(a))
输出结果则为可变数据
这些说明能进行append(),pop(),remove()操作的都是可变数据
七 函数中的可变数据
当可变数据为全局变量时,在函数中对可变数据进行修改也会改变全局变量。
def fun():
a.reverse()
print(a)
a=[1,3,2]
fun()
print(a)
运行结果:
这说明,在函数内外改变的是同一个变量,对同一个地址块上的数据进行修改
再来一个例子:
def fun():
a.append(5)
return a
a=[1]
b=fun()
c=fun()
print(a)
print(b)
print(c)
看到结果前,你们会不会觉得a,b,c的值肯定会不同
然而结果是:。
这更说明在函数内外改变的是同一个变量,对同一个地址块上的数据进行修改 。这就是可变变量的特点。
八 导入其他模块中的函数
使用import
语句导入模块或特定函数。
首先我们先创建一个python文件
下面是几种引用方法
1 直接引用
import bao
a=bao.fun(1)
print(a)
2 引用as换名
可以简写包名
import bao as b
a=b.fun(1)
print(a)
1,2的输出结果
我们可以看出,多出了一个‘我爱学python!’这句话,因为在我们import一个包之后就相当于把那个包的代码全部复制在你import的地方了,所以就会运行,这里我们可以用3,4方法只引用函数。
3 只导入函数、
这个作用是在用函数时不用再写包了
from bao import *
a=fun(1)
print(a)
4 引用具体函数
form bao import fun
a=fun(1)
print(a)
1,2,3,4的输出结果
我们可以看出,多出了一个‘我爱学python!’这句话,因为在我们import一个包之后就相当于把那个包的代码全部复制在你import的地方了,所以就会运行,这里我们可以用__name__属性。
九 __name__属性
在以为我们可能会编写大项目,函数和主函数分离,但是我们又想测试下我们写的函数有没有bug,可能就会在函数下面测试了,但是就会出现一个问题,我们写的测试函数会在被引用时直接执行,这样就不利于运行,所以我们可以引用 __name__属性,我们只要在
if __name__=='__main__':
下面写,这样这个代码只会在当下文件中运行,导入到其他包中就不会运行。
十 lambda函数
Lambda函数是一种匿名函数,通常用于简化代码,无需使用def
关键字定义函数名。它适合短小的逻辑,可以接受任意数量的参数,但只能包含单个表达式,并自动返回表达式的结果。
Lambda函数的语法
基本语法格式为:
lambda 参数列表: 表达式
例如,计算两数之和的Lambda函数:
add = lambda x, y: x + y
print(add(3, 5)) # 输出8
#相当于
def fun(a,b):
return a+b
print(fun(3,5))
Lambda函数的常见用途
作为排序的键函数
pairs = [(1, 'a'), (3, 'c'), (2, 'b')]
sorted_pairs = sorted(pairs, key=lambda x: x[1]) # 按字母排序
Lambda函数的限制
- 只能包含一个表达式,不能包含复杂逻辑或多条语句。
- 无法直接调用
print()
等语句(需通过表达式实现)。
示例:条件表达式
max_value = lambda a, b: a if a > b else b
print(max_value(10, 20)) # 输出20
十一 递归函数
递归函数是指在函数定义中调用自身的方法。通过将问题分解为更小的相似子问题,递归可以简化复杂任务的实现。递归通常包含两个关键部分:停止递归的条件和调用自身的条件)。
计算阶乘
阶乘(n!)的递归实现:
def factorial(n):
if n == 1: # 基线条件
return 1
else: # 递归条件
return n * factorial(n - 1)