前言
在 Python 中,函数是将一段实现功能的完整代码,使用函数名称进行封装,通过函数名称进行调用。以此达到一次编写,多次调用的目的。它可以接受输入参数,并返回一个或多个值。
一、函数基础
1. **定义函数**
#自定义函数
def 函数名称 (参数列表):
函数体
[return 返回值列表]
2. **函数调用**
def get_sum(num):
s=0
for i in range(1,num+1):
s+=i
print (f'1到{num}之间的累加和为:{s}')
#函数的调用
a=get_sum(8)
# 1到8之间的累加和为:36
a=get_sum(100)
# 1到100之间的累加和为:5050
a=get_sum(1000)
# 1到1000之间的累加和为:500500
3. **参数传递**
- 传递的是对象的引用
- 不可变对象(数字、字符串、元组)传值
- 可变对象(列表、字典)传引用

二、参数类型

1. **位置参数**
def happy_birthday(name,age):
print('祝'+ name +'生日快乐!')
print(str(age)+'岁生日快乐!')
#调用
a=happy_birthday('小美',18)
# 祝小美生日快乐!
# 18岁生日快乐!
--------------------------------------------------------------------
#报错演示
a=happy_birthday('小美')
# Traceback (most recent call last):
# File "f:\Code\Python\test.py", line 12, in <module>
# a=happy_birthday('小美')
# TypeError: happy_birthday() missing 1 required positional argument: 'age'
a=happy_birthday(18,'小美')
# Traceback (most recent call last):
# File "f:\Code\Python\test.py", line 18, in <module>
# a=happy_birthday(18,'小美')
# File "f:\Code\Python\test.py", line 2, in happy_birthday
# print('祝'+ name +'生日快乐!')
# TypeError: can only concatenate str (not "int") to str
2. **关键字参数**
def happy_birthday(name,age):
print('祝'+ name +'生日快乐!')
print(str(age)+'岁生日快乐!')
#调用,关键字传参
a=happy_birthday(age=21,name='小美')
# 祝小美生日快乐!
# 21岁生日快乐!
#位置参数+关键字参数,位置参数必须在前面
a=happy_birthday('小红',age=25)
# 祝小红生日快乐!
# 25岁生日快乐!
#报错演示
#--------------------------------------------------------------------
a=happy_birthday(age=25,'小红')
# PS F:\Code\Python> & D:/python/python.exe f:/Code/Python/test.py
# File "f:\Code\Python\test.py", line 19
# a=happy_birthday(age=25,'小红')
# ^
# SyntaxError: invalid decimal literal
# PS F:\Code\Python>
3. **默认参数**
def happy_birthday(name='小美',age=18):
print('祝'+ name +'生日快乐!')
print(str(age)+'岁生日快乐!')
#调用函数
happy_birthday()
# 祝小美生日快乐!
# 18岁生日快乐!
#调用函数
happy_birthday(age=25,name='小红')
# 祝小红生日快乐!
# 25岁生日快乐!
happy_birthday(age=29)
# 祝小美生日快乐!
# 29岁生日快乐!
happy_birthday(29)
# Traceback (most recent call last):
# File "f:\Code\Python\test.py", line 18, in <module>
# happy_birthday(29)
# File "f:\Code\Python\test.py", line 2, in happy_birthday
# print('祝'+ name +'生日快乐!')
# TypeError: can only concatenate str (not "int") to str
⚠️ 默认参数应该使用不可变对象
4. **可变参数**

- `*args` 接收元组
def fun(*para):
print(type(para))
for item in para:
print (item)
#调用
fun(10,23,36,38,90)
# <class 'tuple'>
# 10
# 23
# 36
# 38
# 90
#传个列表玩玩
fun([1,2,3,4,5,6])
# <class 'tuple'>
# [1, 2, 3, 4, 5, 6]
#对比下差距,这叫做解包操作
fun(*[1,2,3,4,5,6])
# <class 'tuple'>
# 1
# 2
# 3
# 4
# 5
# 6
- `**kwargs` 接收字典
#个数可变的关键字参数
def fun(**kw):
print(type(kw))
for k,v in kw.items():
print(k,'-------',v)
#调用,关键字传参
fun(name='小美',age=18,height=172)
# <class 'dict'>
# name ------- 小美
# age ------- 18
# height ------- 172
d={'name':'小美','age':20,'height':'182'}
fun(**d) #**解包操作
# <class 'dict'>
# name ------- 小美
# age ------- 20
# height ------- 182
fun(d) #报错
# Traceback (most recent call last):
# File "f:\Code\Python\test.py", line 21, in <module>
# fun(d)
# TypeError: fun() takes 0 positional arguments but 1 was given
# PS F:\Code\Python>
5. **参数组合顺序**
def func(a, b=0, *args, c, d=1, **kwargs):
pass
正确顺序:位置参数 → 默认参数 → *args → 关键字参数 → **kwargs
三、返回值

1. 可返回多个值(实际返回元组)
def calc(a,b):
s=a+b
return s
a=calc(10,20)
print(type(a))
print(a)
# <class 'int'>
# 30
get_s2=calc(calc(10,20),30)
print(get_s2)
# 60
#返回多个值
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+=i
else:
even_sum+=i
s+=i
return odd_sum,even_sum,s
result=get_sum(10)
print(type(result))
print(result)
# <class 'tuple'>
# (25, 30, 55)
#解包赋值
a,b,c=get_sum(10)
print(a)
print(b)
print(c)
# 25
# 30
# 55
2. 函数没有return语句时返回None
def calc(a,b):
print(a+b)
calc(10,20)
#30
a=calc(10,20)
print (type(a))
print(a)
# 30
# <class 'NoneType'>
# None
四、作用域

#局部变量在全局中无法使用
def fun(a,b):
s = a + b
fun (10,20)
print (a,b,s)
# Traceback (most recent call last):
# File "f:\Code\Python\test.py", line 6, in <module>
# print (a,b,s)
# NameError: name 'a' is not defined
#函数内部变量指定成全局变量
def fun(a,b):
global s #声明是全局变量
s = a + b
fun(10,20)
print (s)
#30
#哪个变量优先级高
x=100
def fun(a,b):
x = 10 #局部变量名称与全局变量名称相同
s = a + b + x #局部变量参与运算,局部变量优先级高
return s
test=fun(10,20)
print(test)
1. **LEGB规则**
- Local → Enclosed → Global → Built-in
2. **global 关键字**
```python
x = 10
def modify():
global x
x = 20
```
3. **nonlocal 关键字**
```python
def outer():
x = 1
def inner():
nonlocal x
x = 2
```
五、高级特性
1. **匿名函数 lambda**

#常规函数
def calc(a,b):
return a + b
print(calc(10,20))
#匿名函数
s=lambda a,b:a+b #s表示的就是匿名函数
print(type(s))
# <class 'function'>
#调用匿名函数
print (s(20,50))
#70
#列表
lst=[10,20,30,40,50]
for i in range(len(lst)):
print (lst[i])
# 10
# 20
# 30
# 40
# 50
for i in range(len(lst)):
result=lambda x:x[i] #根据索引值,result是函数类型,x是形式参数
print(result(lst))#lst是实际参数
# 10
# 20
# 30
# 40
# 50
#根据成绩排名打印
student_scores=[
{'name':'陈小明','score':98},
{'name':'王一一','score':86},
{'name':'天小红','score':100},
{'name':'白雪儿','score':91}
]
student_scores.sort(key=lambda x:x.get('score'),reverse=True) #降序排列
print(student_scores)
# [{'name': '天小红', 'score': 100}, {'name': '陈小明', 'score': 98}, {'name': '白
# 雪儿', 'score': 91}, {'name': '王一一', 'score': 86}]
2. **递归函数**

#递归函数
#阶乘操作
def fac(n):
if n == 1:
return 1
else:
return n*fac(n-1)
print(fac(5))
#120 5*4*3*2*1
#斐波那契数列 f(n)=f(n-1)+f(n-2)
# 从第三项开始,每项等于前两项之和 1 1 2 3 5 8 13 21
def fac2(n):
if n==1 or n==2:
return 1
else:
return fac2(n-1)+fac2(n-2)
print(fac2
3. **闭包**
```python
def make_multiplier(factor):
def multiply(x):
return x * factor
return multiply
times3 = make_multiplier(3)
```
4. **装饰器**
```python
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
print(f"Time used: {time.time()-start}")
return result
return wrapper
@timer
def my_function():
# ...
```
六、其他特性
1. **函数注释**
```python
def add(x: int, y: int) -> int:
return x + y
```
2. **函数作为参数传递**
```python
def apply(func, data):
return [func(x) for x in data]
```
3. **参数解包**
```python
args = (3, 4)
kwargs = {'b': 5, 'a': 6}
func(*args) # 等价于 func(3, 4)
func(**kwargs) # 等价于 func(a=6, b=5)
```
---
### 注意事项
1. 避免修改可变默认参数
2. 装饰器会改变函数的元信息,可用 `@functools.wraps` 保持原信息
3. 合理控制递归深度(Python默认递归深度不超过1000)
建议通过实际编写不同参数组合的函数来加深理解,可以使用 `help(function_name)` 查看函数的文档字符串,`dir(function_name)` 查看函数属性。