1.Python3函数:让代码"打包复用"
你是否发现自己在代码中反复写着一模一样的片段?就像每次做饭都要从头切菜洗菜一样,函数就是帮你把这些重复操作打包成固定流程的好帮手。
什么是函数?
想象函数就像一个厨房小家电------你放入食材(输入),它按照预设程序工作,然后给你成品(输出)。你不用关心内部怎么运转,只需要知道怎么使用它
定义你的第一个函数
python
def say_hello():
print("你好,世界!")
print("欢迎来到Python函数的世界")
以上代码中:
def是定义函数的关键字,意思是"定义"say_hello是函数名,按你的需求起名- 括号
()目前空着,后面会放参数 - 冒号
:表示函数内容开始 - 缩进的代码就是函数体,是函数具体要做的事
调用函数------让它真正工作
python
# 定义函数
def say_hello():
print("你好,世界!")
print("欢迎来到Python函数的世界")
# 调用函数三次
say_hello()
say_hello()
say_hello()
运行这段代码,你会发现同样的问候语出现了三次,但你只写了一次逻辑------这就是函数的复用价值
让函数更灵活:添加参数
固定的问候太单调,让我们个性化一点:
python
def greet_person(name):
print(f"你好,{name}!")
print("今天过得怎么样")
# 调用时传入不同名字
greet_person("小明")
greet_person("小美")
现在每次调用都能问候不同的人,name 就是参数,像函数的"输入插槽"
函数返回值------得到结果
很多时候我们需要函数计算后给我们一个结果:
python
def add_numbers(a, b):
result = a + b
return result
# 接收返回值
sum_result = add_numbers(5, 3)
print(f"5加3等于{sum_result}")
return 就像函数的"输出口",把结果送出来供你使用
初学者常犯的错误:
python
# ❌ 错误写法:调用在前,定义在后
say_hello() # 这里会报错!
def say_hello():
print("你好")
# ✅ 正确写法:定义在前,调用在后
def say_hello():
print("你好")
say_hello() # 这样才对
记住,Python是从上往下执行代码的,所以函数定义要在调用之前
动手试试
现在轮到你了,试着写一个函数:
- 函数名:
calculate_area - 参数:
length(长),width(宽) - 功能:计算长方形面积
- 返回:面积值
2.核心参数类型速览
为了让你一目了然,我整理了一个表格来概括这几种参数:
| 参数类型 | 关键符号 | 作用说明 |
|---|---|---|
| 位置参数 | 无 | 最基础的参数,按顺序传递,必须传值。 |
| 默认参数 | param=value |
调用时可以省略,使用定义时的默认值。 |
| 可变位置参数 | *args |
接收任意多个无名 参数,打包成元组。 |
| 可变关键字参数 | **kwargs |
接收任意多个有名 参数,打包成字典。 |
| 关键字参数 | * |
强制要求调用时必须使用"参数名=值"的形式。 |
📝 1. 详细解析与代码示例
(1) 位置参数 (Positional Arguments)
这是最常见、最简单的参数。你必须按照函数定义时参数的顺序,依次传入对应数量的值。
python
def greet(name, greeting):
return f"{greeting}, {name}!"
# "Alice" 传给 name, "Hello" 传给 greeting
print(greet("Alice", "Hello"))
第一个值给name,第二个给greeting
(2) 默认参数 (Default Arguments)
在定义函数时给参数指定一个默认值。如果调用时不传这个参数,就用默认值;传了就用传入的值。
- 注意: 默认参数必须放在必选参数之后。
- 避坑: 尽量不要使用可变对象(如列表
[]或字典{})作为默认值,否则可能会导致奇怪的副作用。
python
def greet(name, greeting="Hello"): # greeting 有默认值
return f"{greeting}, {name}!"
print(greet("Bob")) # 只传一个,使用默认问候语
print(greet("Charlie", "Hi")) # 两个都传,覆盖默认值
(3) 可变位置参数 (*args)
当你不确定要传多少个参数时使用。在参数名前加一个星号 *,函数会把多余的位置参数收集到一个元组中。
python
def sum_all(*numbers):
# numbers 是一个元组 (1, 2, 3, 4)
return sum(numbers)
print(sum_all(1, 2, 3, 4)) # 可以传任意多个数字
(4) 可变关键字参数 (**kwargs)
用来接收任意多个"关键字=值"的参数。在参数名前加两个星号 **,函数会把这些参数收集到一个字典中。
python
def user_info(**details):
# details 是一个字典 {'name': 'Alice', 'age': 25}
for key, value in details.items():
print(f"{key}: {value}")
user_info(name="Alice", age=25, city="Beijing")
(5) 关键字参数 (Keyword-Only)
在 *args 后面的参数,或者单独使用 * 分隔的参数,被称为"强制关键字参数"。调用时必须写明参数名,否则会被当作位置参数处理,导致报错。
python
def calculate(*, tax_rate, amount):
# * 后面的参数必须用关键字传参
return amount * tax_rate
# 必须这样调用:
calculate(tax_rate=0.1, amount=100)
# 如果写成 calculate(0.1, 100) 会报错!
(6) 参数解包 (Unpacking)
这不算是函数定义的参数类型,但在传参时非常有用。你可以使用 * 或 ** 将列表/元组、字典解开,作为参数传入函数。
python
def func(a, b, c):
print(a, b, c)
args_list =
func(*args_list) # 解包列表,相当于 func(1, 2, 3)
kwargs_dict = {'a': 1, 'b': 2, 'c': 3}
func(**kwargs_dict) # 解包字典,相当于 func(a=1, b=2, c=3)
⚖️ 2. 组合使用的规则
在一个函数定义中,你可以混合使用上述参数,但必须严格遵守以下顺序,否则 Python 会报错:
- 位置参数 (positional)
- 默认参数 (default)
- 可变位置参数 (
*args) - 关键字参数 (keyword-only)
- 可变关键字参数 (
**kwargs)
一个综合示例:
python
def example_func(pos1, pos2, default1=0, *args, kw_only, **kwargs):
print(f"位置参数: {pos1}, {pos2}")
print(f"默认参数: {default1}")
print(f"可变位置参数 (*args): {args}")
print(f"强制关键字参数: {kw_only}")
print(f"可变关键字参数 (**kwargs): {kwargs}")
# 调用示例
example_func(1, 2, 3, 4, 5, kw_only="必须指定", extra="额外信息")
3.匿名函数
想象你需要一把一次性螺丝刀------只拧一颗螺丝后就扔掉,不值得买整套工具。匿名函数就是这样的"一次性工具函数",没有正式名字,定义后立即使用或传递给其他函数
匿名函数使用 lambda 关键字定义,语法:
lambda 参数: 表达式
对比普通函数,匿名函数的特点:
-
没有
def和函数名 -
只有一行表达式
-
自动返回表达式结果,无需
return对比两种写法
# 普通函数写法 def add_regular(x, y): return x + y # 匿名函数写法 add_lambda = lambda x, y: x + y # 两种方式效果相同 print(add_regular(3, 5)) # 输出 8 print(add_lambda(3, 5)) # 输出 8
函数让代码变得更简洁、更易维护,就像把杂乱的工具整理进工具箱,需要时随时取用
Python 的参数是函数调用时被传进去的值
匿名函数的限制
python
# ❌ 不能有多条语句
# lambda x: print(x); return x * 2 # 错误!
# ✅ 但可以使用条件表达式
grade_check = lambda score: "优秀" if score >= 90 else "及格" if score >= 60 else "不及格"
print(grade_check(95)) # 输出 "优秀"
print(grade_check(75)) # 输出 "及格"
匿名函数只能包含单个表达式,但可以使用三元条件表达式实现简单逻辑
总结:
1.用def定义函数、通过return返回值,理解函数成为代码复用的基石
2.参数篇深入探讨各种参数类型:基础的位置参数、灵活的默认参数,到强大的*args和**kwargs,再到精确控制的关键字参数。记住那个关键顺序:位置→默认→可变位置→关键字→可变关键字
3.匿名函数则让我们看到了代码的另一种可能性------简洁的lambda表达式