跳到主要内容

函数参数与调用

函数一旦开始多写,参数设计就会直接影响可读性。很多“代码能跑但不好用”的函数,问题往往不在逻辑,而在参数接口设计得不清楚。

位置参数

最基础、最常见的方式:

def greet(name, age):
print(f"{name} is {age} years old.")


greet("alice", 20)

调用时按顺序传值。

关键字参数

def greet(name, age):
print(f"{name} is {age} years old.")


greet(age=20, name="alice")

这种写法更适合参数较多、或者同类型参数容易传错顺序的场景。

默认参数

def connect(host, port=3306):
print(host, port)


connect("localhost")
connect("localhost", 5432)

默认参数可以降低调用成本,但不要把“总是变化的参数”也硬塞成默认参数。

*args:接收任意多个位置参数

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


print(total(1, 2, 3, 4))

这适合参数个数不固定的情况。

**kwargs:接收任意多个关键字参数

def print_config(**kwargs):
for key, value in kwargs.items():
print(key, value)


print_config(host="localhost", port=3306, debug=True)

参数顺序要有规则

一个函数里如果参数类型比较丰富,顺序通常遵循:

  1. 普通位置参数
  2. 默认参数
  3. *args
  4. 关键字专用参数
  5. **kwargs

例如:

def func(a, b=0, *args, sep=",", **kwargs):
...

一个非常常见的坑:可变对象默认参数

不推荐这样写:

def append_item(item, container=[]):
container.append(item)
return container

更稳妥的方式:

def append_item(item, container=None):
if container is None:
container = []
container.append(item)
return container

原因是默认参数只会在函数定义时创建一次,不会每次调用都重新创建。

我更推荐的参数设计习惯

  • 参数少而明确时,用位置参数
  • 容易看不懂顺序时,用关键字参数
  • 只有在确实需要“不定参数”时才用 *args / **kwargs
  • 默认参数尽量用不可变值

关联阅读