当前位置:首页>python>Python入门——函数基础

Python入门——函数基础

  • 2026-10-10 14:25:14
Python入门——函数基础

6. 把代码打包(上)——函数基础

读完本节,你能在 20 分钟内,用 def 把重复代码封装成函数,掌握位置 / 默认值 / 关键字 3 种参数,并用 docstring 写函数文档。

函数是“有名字的代码块”,核心目的是减少重复。

6.1 为什么用函数?

假设要打印 5 遍九九乘法表的一行:

print(f"1 × 1 = 1")
print(f"1 × 2 = 2")
print(f"1 × 3 = 3")
print(f"1 × 4 = 4")
print(f"1 × 5 = 5")

如果改成函数:

defprint_99(n):
print(f"1 × {n} = {n}")

for n inrange(1, 6):
    print_99(n)

要改公式只改函数体,不用满世界找重复代码。

用函数的 3 个好处:

  1. 可读性
    :greet(“小明”) 比 3 行 print 清楚得多
  2. 可维护
    :要改逻辑只改一处,而不是满文件找
  3. 可复用
    :写一次,到处调用 —— 不同地方传不同参数

💡 小贴士:一个函数只做一件事。如果你在写函数时用了一大段注释解释“这个函数做什么”,大概率应该拆成多个函数。

6.2 定义与调用

defsay_hello(name):             # def 关键字定义函数
"""打印问候语"""# docstring,后面 6.5 节会详细讲
print(f"你好,{name}!")

say_hello("小明")  # 调用:传一个位置参数 name="小明"

输出:

你好,小明!

函数命名也有一些约定:

  • 用动词或动词短语(函数是“做一件事”)
  • 全小写 + 下划线,跟变量一样
  • 避免跟内置函数同名(listdictstrid 等)
defcalculate_total():    # 好
defprocess_data():        # 好
deflist():                # 糟(覆盖了内置 list!)
defList():                # 合法但糟(易混)

💡 小贴士:函数先定义、后调用。把 say_hello(“小明”) 放到 def 上面会报 NameError。Python 自上而下执行,变量和函数都得先定义再使用。

6.3 没有 return 默认返回 None

defadd(a, b):
    result = a + b

print(add(1, 2))  # None(函数没 return,默认返回 None)

要返回值必须用 return:

defadd(a, b):
return a + b

print(add(1, 2))  # 3

return 一执行,函数立即结束,后面的代码不跑:

defcheck(age):
if age < 0:
return"不合法"
if age < 18:
return"未成年"
return"成年"

print(check(25))  # 成年

一次返回多个值其实是元组(S4.3 节会展开):

defget_stats(numbers):
"""返回 (和, 平均, 最大, 最小)"""
returnsum(numbers), sum(numbers) / len(numbers), max(numbers), min(numbers)

total, avg, hi, lo = get_stats([1, 2, 3, 4, 5])
print(f"和={total} 平均={avg} 最大={hi} 最小={lo}")
# 和=15 平均=3.0 最大=5 最小=1

📌 对比 print vs return:

  • print(x)
     —— 把 x 显示在屏幕上,不返回值
  • return x
     —— 把 x 作为函数的“答案”交回给调用者,不显示

新手最常犯的错:在函数里 print 完不 return,然后期望调用者拿到那个值 —— 拿到的是 None。记住:函数想“给外面东西”就用 return,屏幕显示只是副作用。

6.4 参数三种形态

形态 1:位置参数(按顺序传)

defgreet(name, msg):
print(f"{name},{msg}")

greet("小明", "你好")  # 小明,你好

形态 2:默认值参数(不传就用默认值)

defgreet(name, msg="你好"):  # 默认值参数必须放最后
print(f"{name},{msg}")

greet("小明")              # 小明,你好
greet("小明", "早上好")    # 小明,早上好

形态 3:关键字参数(按名字传,顺序无所谓)

defgreet(name, msg):
print(f"{name},{msg}")

greet(msg="早上好", name="小明")  # 小明,早上好

📌 对比:位置参数必须按顺序,关键字参数按名字。混用时,关键字参数必须在位置参数后面:

greet("小明", msg="你好")  # ✓ 合法
greet(name="小明", "你好")  # ✗ SyntaxError

进阶:不定参数(*args / **kwargs)和仅关键字参数(* 之后只能关键字传):

defgreet(name, *, msg="你好"):  # * 之后只能关键字传
print(f"{name},{msg}")

greet("小明")               # 小明,你好
greet("小明", msg="嗨")    # 小明,嗨
greet("小明", "嗨")        # TypeError

这个写法常用于“必须显式标明”的参数,避免误用。

实参解包:用 * / ** 把列表 / 字典“展开”作为参数:

args = ["小明", "早上好"]
greet(*args)  # 等价于 greet("小明", "早上好")

kwargs = {"name": "小明", "msg": "嗨"}
greet(**kwargs)  # 等价于 greet(name="小明", msg="嗨")

这种写法在“配置参数”场景特别常见。

6.5 docstring 与类型提示

defcelsius_to_fahrenheit(c: float) -> float:
"""把摄氏度转华氏度

    Args:
        c: 摄氏度数值

    Returns:
        华氏度数值
    """

return c * 9 / 5 + 32

print(celsius_to_fahrenheit(25))  # 77.0
help(celsius_to_fahrenheit)       # 在终端打印 docstring

Python 3.5+ 还可以加类型提示(type hint)—— : float 表示参数期望是浮点数,-> float 表示返回值是浮点数。类型提示不影响运行,但能让 IDE 帮你检查错误:

defadd(a: int, b: int) -> int:
return a + b

把鼠标悬停到 add("hi", "you") 上,VS Code 会提示“期望 int,实际 str”。这是大型项目里避免低级 bug 的利器。

类型提示还能写复杂结构(用 typing 模块):

from typing importList, Dict, Optional

defprocess_scores(scores: List[int], user: Optional[Dict] = None) -> float:
"""算平均分,user 可选"""
if user isNone:
        user = {}
returnsum(scores) / len(scores) if scores else0.0

初学阶段只用最简单的标注(intstrfloatboolListDict)就够了。

lambda 表达式(匿名函数,适合一次性的小函数):

add = lambda a, b: a + b
print(add(3, 5))  # 8

# 常见用法:排序时传 key
nums = [(1, "b"), (3, "a"), (2, "c")]
nums.sort(key=lambda x: x[1])  # 按第二个元素排序
print(nums)  # [(3, 'a'), (1, 'b'), (2, 'c')]

💡 小贴士:在 VS Code 里把鼠标悬停在函数名上,会自动显示 docstring。写函数时养成写 docstring + 类型提示的习惯,3 个月后回来看代码会感谢自己。Lambda 只用于“短小的一次性函数”,复杂逻辑还是用 def。

🎯 动手练

写一个函数 bmi(weight_kg, height_m),计算并返回 BMI 指数(公式:体重(kg) / 身高(m)²)。加 docstring 说明参数和返回值。再写一个函数 bmi_category(bmi),根据 BMI 返回分类(“偏瘦” / “正常” / “偏胖” / “肥胖”)。

预期:

print(bmi(70, 1.75))          # 22.857...
print(bmi_category(22.86))    # 正常

练习参考答案

defbmi(weight, height):
"""计算 BMI"""
return weight / height ** 2

defbmi_category(b):
if b < 18.5: return"偏瘦"
if b < 24:   return"正常"
if b < 28:   return"偏胖"
return"肥胖"

本节小结

  • 函数 = 有名字的代码块,用 def 定义;函数命名用动词 / 动词短语,小写 + 下划线
  • 一个函数只做一件事(Single Responsibility),复杂逻辑要拆
  • 没有 return 默认返回 None;return 一执行函数立即结束
  • print
     是副作用(显示),return 是返回值;两者用途不同,新手最常搞混
  • 三种参数:位置参数、默认值参数(放最后)、关键字参数
  • 关键字参数可打乱顺序,但混用时必须在位置参数之后
  • *
     之后只能关键字传;*args / **kwargs 处理任意多参数(下节详讲)
  • docstring 写在函数第一行(三引号),help(函数名) 查看
  • Python 3.5+ 类型提示 : int-> float 让 IDE 帮你检查错误,不影响运行
  • lambda 是匿名函数,适合一次性的小函数,复杂逻辑用 def

最新文章

随机文章