小甲鱼 发表于 2026-2-11 02:58:17

本主题需向作者支付 5 鱼币 才能浏览 购买主题

a247863072 发表于 2026-5-29 18:05:46

@FishC 已定义函数如下,请问以下哪次调用会因为“缺少必须的参数”而报错?

def encrypt(text, /, *, salt):
    return f'{text}#{salt}'

A. encrypt('ping', salt='42')
B. encrypt('ping')
C. encrypt('ping', '42')
D. encrypt(text='ping', salt='42')
为什么C不会报错,不是说*号后面的必须是关键字参数吗

FishC 发表于 2026-5-29 18:05:58

a247863072 发表于 2026-05-29 18:05
@FishC 已定义函数如下,请问以下哪次调用会因为“缺 ...

根据函数定义 def encrypt(text, /, *, salt)::

- / 前面的参数 text 仅限位置传递,不能使用关键字。
- * 后面的参数 salt 仅限关键字传递,且没有默认值,是必须提供的。

选项分析:


[*]A:encrypt('ping', salt='42') — 正确,位置参数 + 关键字参数。
[*]B:encrypt('ping') — 缺少必须的关键字参数 salt,会报错“缺少必须的参数”。
[*]C:encrypt('ping', '42') — 传入两个位置参数,但函数只能接受一个位置参数,因此报错类型是 takes 1 positional argument but 2 were given,并非“缺少必须的参数”。
[*]D:encrypt(text='ping', salt='42') — text 是仅限位置参数,不能使用关键字传递,报错类型是 got some positional-only arguments passed as keyword arguments。


因此,只有 B 是因为“缺少必须的参数”而报错。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

a247863072 发表于 2026-5-29 18:13:52

@FishC 如果有函数是 def mix(a, b, /, c, d=0, *, e, f=1): ...。其中哪些参数是“仅限位置参数”?
A. a, b
B. c, d
C. d, e
D. e, f
斜杠和*中间的那两个是什么?我上一次看题目说e,f=1只有仅限使用关键字参数,但在def后面f=1不是已经设置成了默认参数吗?然后斜杠和*中间的C,d,其中D是默认参数,C在星号前可以是任意参数,但同时在斜杠后必须是关键字参数,那之前的题目仅限关键字参数的答案应该是C和e,为什么是ef呢?这一题ab大概是因为在斜杠前,没什么好说的,我做错的是上一题

FishC 发表于 2026-5-29 18:14:02

a247863072 发表于 2026-05-29 18:13
@FishC 如果有函数是 def mix(a, b, /, c, d=0, *, e, ...

关于您的问题,我们来逐一理清。

混音函数定义:def mix(a, b, /, c, d=0, *, e, f=1): ...的参数规则如下:

1. 仅限位置参数:斜杠 / 之前的所有参数(即 a 和 b)是仅限位置参数,不能通过关键字传递。

2. 位置或关键字参数:位于斜杠 / 和星号 * 之间的参数(即 c 和 d=0)既可以通过位置传递,也可以通过关键字传递。注意:这里的 d=0 虽然是默认参数,但仍然是位置或关键字参数,不是“仅限关键字”。

3. 仅限关键字参数:星号 * 之后的所有参数(即 e 和 f=1)是仅限关键字参数,必须通过关键字传递。即使 f=1 有默认值,它依然是仅限关键字参数。

因此,题目问“哪些参数是仅限位置参数?”正确答案是 A. a, b。

您提到的上一题(关于仅限关键字参数),答案应该是 e, f(即选项 D),而不是 c, e。您的误解在于误以为斜杠后的 c 也属于仅限关键字,实际上它属于“位置或关键字”范畴。星号才是划分仅限关键字参数的分界线。

总结:

[*] 仅限位置:斜杠前。
[*] 位置或关键字:斜杠后、星号前。
[*] 仅限关键字:星号后。


希望这个解释能帮您纠正之前的错误理解。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

a247863072 发表于 2026-5-29 18:22:10

@FishC 执行以下代码后,输出结果是什么?

def ticket(city, price=50):
    return f'{city}:{price}元'

print(ticket('苏州'))

A. 苏州:50元
B. 苏州:price元
C. 50:苏州元
D. 会报错,因为没传 price

FishC 发表于 2026-5-29 18:22:15

a247863072 发表于 2026-05-29 18:22
@FishC 执行以下代码后,输出结果是什么?

def tic ...

输出结果为 苏州:50元,故选 A.

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

a247863072 发表于 2026-5-29 18:39:05

@FishC 如果有函数是 def mix(a, b, /, c, d=0, *, e, f=1): ...。默认参数不是应该放到最末尾吗?为什么这个d=0放在中间?如果一个函数同时有位置参数,关键字参数和默认参数,他们的顺序是什么

FishC 发表于 2026-5-29 18:39:18

a247863072 发表于 2026-05-29 18:39
@FishC 如果有函数是 def mix(a, b, /, c, d=0, *, e, ...

在 Python 中,函数参数的定义顺序是严格规定的。你的例子 def mix(a, b, /, c, d=0, *, e, f=1): ... 完全合法,默认参数 d=0 并没有“放在中间”,而是放在了它该在的位置。

整个参数列表划分成三个区域,由分隔符 / 和 * 界定:

- / 之前:仅位置参数(不能通过关键字传递),可以有默认值,但必须放在最后面。
- / 和 * 之间:普通参数(既可位置也可关键字传递),也支持默认参数,但同样要求无默认值的参数放在有默认值参数之前。
- * 之后:仅关键字参数(只能通过关键字传递),同上。

在你的函数中:

- a, b 是仅位置参数(无默认值)。
- c 是普通参数(无默认值),d=0 是普通参数(有默认值),这里 c 在 d 之前,符合“无默认值的在前,有默认值的在后”的惯例。
- e 是仅关键字参数(无默认值),f=1 是仅关键字参数(有默认值),同样符合顺序。

因此这个定义是正确且合理的。你之所以觉得“默认参数应放在最末尾”,是因为平时接触的函数多属于只有普通参数的情况,此时默认参数自然应放在所有无默认值参数之后。但在引入 / 和 * 后,每个区域内都有自己的“末尾”,且默认参数可以出现在不同区域中。

所以总结一下完整的参数顺序规则:


def func(仅位置参数, /, 位置+关键字参数(无默认值), 位置+关键字参数(有默认值), *, 仅关键字参数(无默认值), 仅关键字参数(有默认值)):
    ...


每个区域内都必须遵循“无默认参数先写,有默认参数后写”的原则。你的 mix 函数完美遵循了这些规则。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

a247863072 发表于 2026-5-29 18:47:47

@FishC 如果有函数是 def mix(a, b, /, c, d=0, *, e, f=1): ...。f=1是关键字参数但有默认值,也就是说一个参数既可以是默认参数也可以同时是关键字或者位置参数,如果有默认值就必须放在那个区域的后面,那么调用的时候,写不写呢?假设我用的时候写mix(1,2,3,e=4,5),机器会知道我省略的是哪个吗?因为这里有个关键字参数e,所以它可能知道,那如果我把星号去掉,新的mix函数是这样设置def mix(a,b,c,d=0,e,f=1)这样我用的时候省略mix(1,2,3,4,5)他知道我省略的是哪个默认参数吗

FishC 发表于 2026-5-29 18:48:05

a247863072 发表于 2026-05-29 18:47
@FishC 如果有函数是 def mix(a, b, /, c, d=0, *, e, ...

在 Python 函数中,参数的默认值、位置和关键字属性的组合确实容易混淆。我们来分解你的两个例子。

**第一个函数:**
def mix(a, b, /, c, d=0, *, e, f=1):

- a, b 是纯位置参数(位于 / 之前)
- c, d 是位置或关键字参数(位于 / 和 * 之间),其中 d 有默认值
- e, f 是仅关键字参数(位于 * 之后),其中 f 有默认值

调用 mix(1, 2, 3, e=4, 5) 会报错,因为 5 是位置参数,但 e=4 之后的参数必须都是关键字形式(即 f=5)。机器不会去“猜测”你省略了哪个默认参数——语法本身就不允许这种写法。

正确的调用方式:
mix(1, 2, 3, e=4, f=5)    # 使用关键字指定 f
mix(1, 2, 3, d=10, e=4, f=5)# 显式指定 d 的值
mix(1, 2, 3, 0, e=4)         # 省略 f,使用默认值 1

**第二个函数:**
def mix(a, b, c, d=0, e, f=1):

所有参数都是位置或关键字(没有 / 和 *)。其中 d 和 f 有默认值,e 没有默认值(它是必需参数)。调用 mix(1, 2, 3, 4, 5) 时,参数按顺序赋值:
- a=1, b=2, c=3, d=4, e=5→ 此时缺少 f,会报错缺少必需参数。

如果希望跳过 d 而只给 e 和 f,必须使用关键字:
mix(1, 2, 3, e=4, f=5)      # d 取默认值 0
mix(1, 2, 3, e=4)         # f 取默认值 1
mix(1, 2, 3, d=10, e=4)   # 显式指定 d

**核心结论:**

- 位置参数的绑定严格按照顺序,从左到右依次匹配。
- 默认参数(有默认值的参数)只能从右向左连续省略。例如参数顺序为 a, b, c=1, d=2,如果调用 func(1, 2) 则 a=1, b=2, c=1, d=2;调用 func(1, 2, 3) 则 c=3, d=2;调用 func(1, 2, 3, 4) 则 c=3, d=4。
- 如果想跳过中间的默认参数(比如跳过 c 直接给 d 赋值),必须使用关键字参数形式: func(1, 2, d=4)。
- 机器不会“猜”你省略的是哪个——它完全依据参数的位置和提供的顺序来匹配。如果位置不匹配或缺少必需参数,就会报错。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 第042讲:函数(II)