Python函数(function)把一段可复用的逻辑起个名字,需要时按名字调用。定义用 def,括号里写参数,函数体缩进。用 return 把结果交回调用方。重复出现的计算、格式化输出、校验步骤,适合收进函数,主流程只保留调用关系。

先写一个函数

最简单的情况是没有参数、也没有返回值,函数体里直接做事。定义之后可以多次调用,不必把同一段代码复制粘贴:

def greet():
    print("Hello!")

greet()
greet()

输出:

Hello!
Hello!

定义、参数与调用

def 后面是函数名和括号,冒号后的缩进块才是函数体。括号里的名字是形参,调用时传入的是实参。形参在函数内部当局部变量用:

def greet(name):
    print(f"你好,{name}")

greet("小明")
greet("小红")

输出:

你好,小明
你好,小红

返回值:return

return 结束当前函数,并把后面的表达式作为结果交给调用方。可以赋给变量,也可以直接嵌进别的表达式。函数里如果一次 return 都没写,调用结果是 None

Python 函数定义与返回值示例运行
def add(a, b):
    return a + b

result = add(3, 5)
print(result)        # 8

def say_hi():
    print("hi")

print(say_hi())      # 先打印 hi,再打印 None

默认参数

形参可以带默认值。调用时若省略对应实参,就用定义时写好的默认值。若传入,则以传入为准。有默认值的参数一般放在参数列表靠后的位置:

def greet(name, greeting="你好"):
    print(f"{greeting},{name}")

greet("小明")
greet("小红", "早上好")

关键字参数

调用时写成 名字=值,就不依赖定义时的先后顺序。位置参数与关键字参数可以混用,但位置实参必须写在关键字实参前面:

def info(name, age, city):
    print(f"{name} {age} {city}")

info(age=20, city="北京", name="小明")
info("小红", 18, "上海")

任意数量参数

参数个数事先不确定时,用 *args 把多余的位置实参收成元组,用 **kwargs 把多余的关键字实参收成字典。名字约定俗成,写成 *nums**kw 也可以:

def total(*nums):
    return sum(nums)

print(total(1, 2, 3))        # 6
print(total(10, 20))         # 30

def show(**kw):
    for k, v in kw.items():
        print(f"{k}={v}")

show(name="Tom", age=18)

更细的传参规则、混合顺序和解包写法,见下一篇《函数参数》

为什么用函数

  • 同一段逻辑写一次,多处调用,减少复制粘贴。
  • 函数名能概括意图,主流程读起来更像步骤清单。
  • 修改实现时通常只动函数内部,调用点可以少改。
  • 可以单独构造输入去验证一个函数的行为。

常见误区

  • 默认参数不要用可变对象。写成 def f(x=[]) 时,那个列表会在多次调用之间共享,应改成 def f(x=None),再在函数里判断后新建列表。
  • 函数要先定义再调用。名字尚未绑定时直接调用,会得到 NameError
  • 需要把结果交给后续代码时,别忘了 return,否则拿到的是 None