python 函数参数的形式以及调用方式

Python 函数的参数系统非常灵活且强大。下面我将系统、清晰、完整地介绍 Python 函数的所有参数形式及其调用方式,并附上实用示例和注意事项。


一、函数参数的形式(定义时)

def 定义函数时,参数可以按以下顺序出现(顺序不能乱!):

def func(
    pos_only, /,          # 1. 仅限位置参数(Python 3.8+)
    standard,             # 2. 标准参数(位置或关键字)
    standard_with_default="default",  # 3. 带默认值的标准参数
    *args,                # 4. 可变位置参数(收集多余位置参数)
    kw_only,              # 5. 仅限关键字参数(必须用关键字传)
    kw_only_with_default=True,      # 6. 带默认值的仅限关键字参数
    **kwargs              # 7. 可变关键字参数(收集多余关键字参数)
):
    pass

完整顺序口诀
仅位置 → 普通参数 → 默认参数 → *args → 仅关键字 → **kwargs

下面我们逐一详解。


二、7 种参数形式详解

1. 仅限位置参数(Positional-Only Parameters)

语法def f(a, b, /): ...
作用:这些参数只能通过位置传参,不能用关键字。

def div(x, y, /):
    return x / y

div(10, 2)      # ✅ OK
div(x=10, y=2)  # ❌ TypeError! x 和 y 是仅位置参数

📌 引入版本:Python 3.8+
用途:保护内部 API,或模拟 C 函数行为(如 len(obj) 不能写成 len(obj=obj))。


2. 标准参数(Standard Parameters)

最常见的形式,既可用位置,也可用关键字传参

def greet(name, greeting):
    print(f"{greeting}, {name}!")

greet("Alice", "Hi")        # 位置传参
greet(greeting="Hello", name="Bob")  # 关键字传参

3. 带默认值的参数(Default Value Parameters)

在标准参数基础上提供默认值,调用时可省略

def connect(host, port=80, ssl=True):
    print(f"Connect to {host}:{port}, SSL={ssl}")

connect("example.com")               # 使用默认 port=80, ssl=True
connect("api.com", port=443)         # 覆盖 port
connect("db.com", ssl=False, port=5432)  # 用关键字灵活传参

⚠️ 重要规则

  • 默认参数必须放在非默认参数之后
  • 默认值在函数定义时计算一次(警惕可变默认值!)

4. 可变位置参数(*args

收集所有多余的位置参数,打包成元组

def sum_all(a, *args):
    return a + sum(args)

sum_all(1)          # args = () → 1
sum_all(1, 2, 3, 4) # args = (2, 3, 4) → 10

5. 仅限关键字参数(Keyword-Only Parameters)

必须用关键字传参,不能靠位置。

def process_data(data, *, encoding='utf-8', errors='strict'):
    # * 之后的参数只能用关键字
    print(f"Encoding: {encoding}, Errors: {errors}")

process_data("text", encoding="ascii")  # ✅
process_data("text", "ascii")           # ❌ TypeError!

💡 技巧:如果不需要 *args,可以用单独的 * 来开启仅关键字参数。


6. 带默认值的仅限关键字参数

和第 3 类类似,但只能用关键字传

def save_file(path, *, backup=True, compress=False):
    print(f"Save {path}, backup={backup}, compress={compress}")

save_file("data.txt", compress=True)  # backup 用默认值

7. 可变关键字参数(**kwargs

收集所有多余的关键字参数,打包成字典

def create_user(name, **kwargs):
    print(f"User: {name}")
    for k, v in kwargs.items():
        print(f"  {k}: {v}")

create_user("Alice", age=30, city="Beijing")
# 输出:
# User: Alice
#   age: 30
#   city: Beijing

三、函数调用的 3 种方式

调用函数时,你可以混合使用以下方式:

1. 位置参数(Positional Arguments)

按参数定义顺序传值。

func(1, 2, 3)

2. 关键字参数(Keyword Arguments)

通过 参数名=值 传参,顺序可变

func(a=1, c=3, b=2)

3. 解包传参(Unpacking Arguments)

*** 解包序列/字典传参。

args = (1, 2, 3)
kwargs = {"x": 10, "y": 20}

func(*args, **kwargs)  # 等价于 func(1, 2, 3, x=10, y=20)

四、调用时的规则(必须遵守!)

  1. 位置参数必须在关键字参数之前

    func(1, 2, x=3)   # ✅
    func(x=3, 1, 2)   # ❌ SyntaxError!
    
  2. 不能重复传同一个参数

    def f(a): ...
    f(1, a=2)  # ❌ TypeError: f() got multiple values for argument 'a'
    
  3. 不能传未定义的参数(除非有 **kwargs

    def f(a): ...
    f(a=1, b=2)  # ❌ TypeError: unexpected keyword argument 'b'
    

五、完整示例:综合所有参数形式

def example(
    a, b, /,               # 仅位置
    c, d=10,               # 标准 + 默认
    *args,                 # 可变位置
    e, f=20,               # 仅关键字 + 默认
    **kwargs               # 可变关键字
):
    print(f"a={a}, b={b}")          # 仅位置
    print(f"c={c}, d={d}")          # 标准
    print(f"args={args}")           # 多余位置参数
    print(f"e={e}, f={f}")          # 仅关键字
    print(f"kwargs={kwargs}")       # 多余关键字参数

# 调用
example(
    1, 2,               # a, b(必须位置)
    3, d=4,             # c=3, d=4
    5, 6, 7,            # *args → (5, 6, 7)
    e=8, f=9,           # e=8(必须关键字), f=9
    x=10, y=11          # **kwargs → {'x':10, 'y':11}
)

输出:

a=1, b=2
c=3, d=4
args=(5, 6, 7)
e=8, f=9
kwargs={'x': 10, 'y': 11}

六、最佳实践建议

场景 建议
参数 ≤2 个 用位置参数即可
参数 ≥3 个或含布尔标志 优先用关键字参数调用(提高可读性)
设计公共 API 对可选配置使用默认参数 + 仅关键字参数
编写装饰器/代理函数 *args, **kwargs 保持通用性
避免可变默认值 None 代替 []{}
# ✅ 安全的默认值写法
def add_item(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

七、总结图(参数定义顺序)

def func(
    pos_only, /,
    standard,
    standard_with_default="default",
    *args,
    kw_only,
    kw_only_with_default=True,
    **kwargs
):

记住这个顺序,你就掌握了 Python 函数参数的全部奥秘!


posted @ 2025-10-14 23:08  悠哉大斌  阅读(16)  评论(0)    收藏  举报