1. 函数
- 函数是一种封装代码的方式,将实现特定功能的代码片段通过函数名称进行封装,通过函数名称调用即可实现功能复用,达到“一次编写,多次调用”的目的。
1.1 内置函数
Python 提供了许多内置函数,可以直接使用,例如:
- 输出函数:
print()
,用于将内容输出到控制台。 - 输入函数:
input()
,用于从用户获取输入。 - 列表自定义函数:
list()
,用于创建列表。 - 还有更多其他内置函数,如
len()
用于获取长度、type()
用于获取数据类型等,这里不再一一列举。
1.2 自定义函数
我们可以根据自己的需求定义函数,其基本语法如下:
def 函数名称(参数列表):函数体[return 返回值列表]
def
是定义函数的关键字。- 函数名称:遵循变量命名规则,应具有描述性,方便理解函数的功能。
- 参数列表:用于接收调用函数时传入的值,可以有多个参数,也可以没有参数。
- 函数体:是函数的具体实现部分,包含一系列语句,完成特定的功能。
return
返回值列表:return
用于返回函数的执行结果,可以返回一个值,也可以返回多个值(以元组形式),如果不写return
,函数默认返回None
。
1.3 函数调用
函数定义后,需要通过函数名称和参数列表来调用它,其语法为:
函数名(参数列表)
1.4 应用示例
示例 1:累加求和
# 累加求和
def get_sum(n):s = 0for i in range(1, n + 1):s += iprint(f"1到{n}的累加和为:{s}")# print('1到{0}的累加和为:{1}'.format(n,s))# print('1到%d的累加和是:%d' %(n,s))get_sum(10) # 函数调用
get_sum(100)
运行结果:
1到10的累加和为:55
1到100的累加和为:5050
示例 2:任意区间求和
# 任意区间求和
def get_sum(a, n):s = 0for i in range(a, n + 1):s += iprint(f"{a}到{n}的累加和为:{s}")get_sum(1, 10)
get_sum(99, 100)
运行结果:
1到10的累加和为:55
99到100的累加和为:199
2. 函数的参数传递
- 函数的参数传递是函数调用时将实际参数传递给形式参数的过程,根据传递方式的不同,参数可以分为以下几种类型:
2.1 位置参数
- 位置参数是指调用函数时,参数的个数和顺序必须与定义的参数个数和顺序相同。
示例
def happy_birthday(name, age):print(f"祝{name}{age}岁生日快乐!")happy_birthday("kyle", 20)
运行结果:
祝kyle20岁生日快乐!
注意事项:
- 定义几个参数,传递几个位置参数。
- 参数位置顺序必须与定义时一致。
- 参数数据类型需要匹配。
2.2 关键字参数
- 关键字参数是在函数调用时,使用“形参名称=值”的方式进行传参,传递参数的顺序可以与定义时参数的顺序不同。
示例
def happy_birthday(name, age):print(f"祝{name}{age}岁生日快乐!")# 关键字传参:指定关键字,不考虑顺序
happy_birthday(age=20, name="kyle")
happy_birthday("rock", 20) # 位置传参
happy_birthday("ming", age=20) # 位置传参 + 关键字传参
运行结果:
祝kyle20岁生日快乐!
祝rock20岁生日快乐!
祝ming20岁生日快乐!
注意事项:
- 函数定义的参数名称与传递的关键字参数名称必须完全一致。
- 当位置参数和关键字参数同时使用时,位置参数必须在关键字参数之前。
2.3 默认值参数
默认值参数是在函数定义时,直接对形式参数进行赋值。在调用时,如果该参数不传值,则使用默认值;如果该参数传值,则使用传递的值。
示例
def happy_birthday(name="kyle", age=18):print(f"祝{name}{age}岁生日快乐!")happy_birthday() # 使用默认值
happy_birthday(age=10) # 关键字传参,覆盖默认值
happy_birthday(name="rock") # 关键字传参,覆盖默认值
happy_birthday("ming") # 位置参数传参,覆盖默认值
运行结果:
祝kyle18岁生日快乐!
祝kyle10岁生日快乐!
祝rock18岁生日快乐!
祝ming18岁生日快乐!
注意事项:
- 默认值参数必须放在参数列表的最后。
- 位置参数和默认值参数同时存在时,位置参数在前,关键字参数和默认值参数在后。
2.4 可变参数
- 可变参数是一种特殊的参数类型,允许函数接收任意数量的参数值。根据参数类型的不同,可变参数分为两种:个数可变的位置参数和个数可变的关键字参数。
2.4.1 个数可变的位置参数
- 个数可变的位置参数是在函数定义时,在参数前加一颗星(
*para
),para
是形式参数的名称。函数调用时,可接收任意个数的实际参数,并将它们放到一个元组中。
示例
def print_args(*args):print("位置参数列表:", args) # args 是一个元组for arg in args:print(arg)# 调用示例
print_args(1, 2, 3, "hello")
print_args([11, 22, 50]) # 实际上传递的是一个参数
运行结果:
位置参数列表: (1, 2, 3, 'hello')
1
2
3
hello
位置参数列表: ([11, 22, 50],)
[11, 22, 50]
参数解包
在调用时,如果已经有一个列表或元组,可以在参数前加一颗星(*
),将列表或元组中的元素作为多个独立的参数传递给函数,这种方式称为解包。
def fun(*para):print(type(para))for item in para:print(item)# 调用示例
fun(10, 20, 30, 0)
fun(10)
fun(20, 40)
fun([11, 22, 50]) # 实际上传递的是一个参数# 在调用时,参数前加一颗星,会将列表进行解包
fun(*[11, 22, 50])
运行结果:
<class 'tuple'>
10
20
30
0
<class 'tuple'>
10
<class 'tuple'>
20
40
<class 'tuple'>
[11, 22, 50]
<class 'tuple'>
11
22
50
2.4.2 个数可变的关键字参数
个数可变的关键字参数是在函数定义时,在参数前加两颗星(**para
),para
是形式参数的名称。函数调用时,可接收任意多个“参数=值”形式的参数,并将它们放到一个字典中。
示例
def print_kwargs(**kwargs):print("关键字参数字典:", kwargs) # kwargs 是一个字典for key, value in kwargs.items():print(f"{key}: {value}")# 调用示例
print_kwargs(name="kyle", age=20, city="Beijing")
运行结果:
关键字参数字典: {'name': 'kyle', 'age': 20, 'city': 'Beijing'}
name: kyle
age: 20
city: Beijing
字典解包
如果已经有一个字典,可以在调用时在参数前加两颗星(**
),将字典中的键值对作为关键字参数传递给函数,这种方式也称为解包。
def fun2(**kwpare):print(type(kwpare))for key, value in kwpare.items():print(key, '-->', value)# 调用示例
fun2(name='kyle', age=8)d = {'name': "kyle", 'age': 20, 'city': "Beijing"}
# fun2(d) # TypeError: fun2() takes 0 positional arguments but 1 was given
fun2(**d) # 传递的参数如果是一个字典,需要加两个**,进行解包
运行结果:
<class 'dict'>
name --> kyle
age --> 8
<class 'dict'>
name --> kyle
age --> 20
city --> Beijing
注意事项
- 个数可变的位置参数和关键字参数不能同时使用。如果需要同时处理位置参数和关键字参数,可以分别使用
*args
和**kwargs
,但*args
必须在**kwargs
之前。 - 解包操作:
- 使用
*
解包列表或元组时,会将其中的元素作为多个独立的位置参数传递。 - 使用
**
解包字典时,会将其中的键值对作为关键字参数传递。
- 使用
- 参数顺序:
- 如果函数同时包含普通位置参数、默认值参数、
*args
和**kwargs
,参数的顺序必须是:普通位置参数 -> 默认值参数 ->*args
->**kwargs
。
- 如果函数同时包含普通位置参数、默认值参数、
综合示例
以下是一个同时使用普通参数、默认值参数、*args
和**kwargs
的函数示例:
def example_function(a, b, c=10, *args, **kwargs):print("普通位置参数:", a, b)print("默认值参数:", c)print("个数可变的位置参数:", args)print("个数可变的关键字参数:", kwargs)# 调用示例
example_function(1, 2, 3, 4, 5, name="kyle", age=20)
运行结果:
普通位置参数: 1 2
默认值参数: 3
个数可变的位置参数: (4, 5)
个数可变的关键字参数: {'name': 'kyle', 'age': 20}
3. 函数的返回值
3.1. 函数的返回值 return
- 函数的返回值是函数执行的结果,使用
return
关键字返回。return
可以出现在函数中的任意位置,用于结束函数的执行,并将结果返回给调用者。
3.1.1 返回单个值
- 如果函数的运行结果需要在其他函数中使用,那么这个函数应该被定义为带返回值的函数。返回值可以是一个值。
示例代码
def calc(a, b):print(a + b) # 仅打印结果,没有返回值calc(10, 20) # 输出 30
print(calc(1, 2)) # 输出 None,因为没有返回值
带返回值的函数
def sum(a, b):s = a + breturn s # 返回计算结果print('--' * 20)get_calc = sum(5, 7) # 调用函数并接收返回值
print(get_calc) # 输出 12
print(sum(get_calc, 6)) # 输出 18
print(sum(4, 2)) # 输出 6
3.1.2 返回多个值
- 函数可以返回多个值,这些值会以元组的形式返回。可以通过解包的方式接收多个返回值。
示例代码
def get_sum(num):s = 0 # 累加和odd_sum = 0 # 奇数累加和even_sum = 0 # 偶数累加和for i in range(1, num + 1):if i % 2 != 0:odd_sum += ielse:even_sum += is += ireturn s, odd_sum, even_sum # 返回多个值result = get_sum(10)
print(type(result), result) # <class 'tuple'> (55, 25, 30)# 解包赋值
sum_val, odd_sum, even_sum = get_sum(10)
print("sum=%d" % sum_val)
print(f"odd_sum={odd_sum}")
print("even_sum={0}".format(even_sum))
3.2. 变量的作用域
- 变量的作用域决定了变量的可用范围。Python 中的变量分为 局部变量 和 全局变量。
3.2.1 局部变量
- 局部变量是在函数内部定义的变量,仅在函数内部有效。函数执行结束后,局部变量的生命周期结束。
示例代码
def calc(a, b):s = a + b # 局部变量return sresult = calc(10, 20)
print(result) # 输出 30# print(a, b, s) # NameError: name 'a' is not defined
# a 和 b 是函数参数,s 是函数内部定义的变量,都是局部变量
3.2.2 全局变量
- 全局变量是在函数外部定义的变量,或者在函数内部使用
global
关键字修饰的变量。全局变量的作用范围是整个程序,程序运行结束后,全局变量的生命周期才结束。
示例代码
a = 50 # 全局变量def calc(x, y):return a + x + y # 使用全局变量 asum1 = calc(1, 2)
print(sum1) # 输出 53
3.2.3 局部变量与全局变量的冲突
- 如果局部变量和全局变量的名称相同,局部变量的优先级更高。
示例代码
a = 50 # 全局变量def calc2(x, y):a = 200 # 局部变量,与全局变量同名print(a + x + y) # 使用局部变量 acalc2(1, 2) # 输出 203
3.2.4 使用 global
关键字
- 在函数内部,如果需要修改全局变量的值,必须使用
global
关键字声明。
示例代码
def calc3(x, y):global s # 使用 global 关键字声明 s 为全局变量s = 300return s + x + yprint(calc3(1, 2)) # 输出 303
print(s) # 输出 300,s 是全局变量
总结
-
函数的返回值:
- 使用
return
返回函数的执行结果。 - 返回值可以是一个值,也可以是多个值(以元组形式返回)。
- 返回值可以被其他函数调用或处理。
- 使用
-
变量的作用域:
- 局部变量:仅在函数内部有效,函数执行结束后销毁。
- 全局变量:在函数外部定义,或在函数内部使用
global
关键字声明,作用范围是整个程序。 - 如果局部变量和全局变量名称相同,局部变量优先级更高。
- 使用
global
关键字可以在函数内部修改全局变量的值。