6

如何为用户在 python 中定义的函数实现“仅位置参数”?

def fun(a, b, /):
    print(a**b)

fun(5,2)        # 25
fun(a=5, b=2)   # should show error
4

3 回答 3

9

在 Python 3.8 之前,/语法只是文档性的。从3.8开始,您可以使用它在函数定义中指定仅位置参数。例子:

def pow(x, y, z=None, /):
    r = x**y
    if z is not None:
        r %= z
    return r

现在pow(2, 10)pow(2, 10, 17)是有效的调用,但pow(x=2, y=10)pow(2, 10, z=17)是无效的。

有关详细信息,请参阅PEP 570 。

于 2019-05-15T12:12:41.573 回答
4

更新:这个答案会越来越过时;请参阅https://stackoverflow.com/a/56149093/1126841


唯一的解决方案是使用*-parameter,如下所示:

def fun(*args):
    print(args[0] ** args[1])

但这有它自己的问题:你不能保证调用者会提供两个参数;您的函数必须准备好处理 0 或 1 个参数。(忽略额外的参数很容易,所以我不会强调这一点。)

于 2018-10-16T16:30:15.733 回答
1

在接受PEP 570之后,在 python 3.8 中添加了仅位置参数功能,然后在函数签名的文档中发现它表明函数不采用任何关键字参数。

函数定义中的参数前正斜杠 (/) 仅是位置参数,斜杠 (/) 后面的参数可以是任何类型的语法。参数仅根据调用函数时的位置映射到仅位置参数。通过关键字(名称)传递仅位置参数是无效的。

以下示例显示仅具有位置参数的函数定义

def foo(a, b, / , x, y):
   print("positional ", a, b)
   print("positional or keyword", x, y)

在上面的函数定义中,参数 a 和 b 必须作为仅位置参数传递,而 x 或 y 可以是位置参数或关键字。

以下函数调用有效

foo(40, 20, 99, 39)
foo(40, 3.14, "hello", y="world")
foo(1.45, 3.14, x="hello", y="world")

以下函数调用将引发异常 TypeError,因为 a 和 be 作为关键字参数传递。

foo(a=1.45, b=3.14, x=1, y=4)

TypeError: foo() 得到了一些作为关键字参数传递的仅位置参数:'a,b'

可以通过在函数定义中添加正斜杠 (/) 作为最后一个参数来定义函数以仅接受位置参数。

def pow(x, y, /):
   return x ** y

在上述函数定义中,所有参数(x 和 y)仅是位置参数。在这里,按名称传递参数无效,这将导致 TypeError。

pow(2, 3); pow(3, 9)有效而pow(x=3, y=9)无效,这将引发 TypeError

在Python Positional Only Parameters中阅读有关函数参数类型和仅位置参数的更多信息

于 2020-01-08T09:53:39.913 回答