为什么要在Python 3.8+中使用位置参数?

busg9geu  于 2023-04-22  发布在  Python
关注(0)|答案(2)|浏览(106)

在Python 3.8中引入了一个新的“仅定位参数”语法。
从文档中的仅位置参数:
有一个新的语法(/)来表示一些函数参数必须按位置指定(即不能用作关键字参数)。这与help()所示的C实现函数的符号相同(由Larry Hastings的Argument Clinic工具生成)。
为什么要使用这种语法?为什么它对代码的用户更好?
在我看来,这使得用户更难指定他们的参数实际上意味着什么,如果他们愿意的话。为什么要让用户更难呢?

brqmpdu1

brqmpdu11#

简单总结一下PEP 570中所述的原理,即添加了仅位置参数的PEP:
1.许多用C实现的内置函数已经不接受关键字参数,甚至在Python 3.8之前也是如此。允许仅位置参数允许Python代码与C代码保持一致
1.一些python类,比如dict类型的构造函数,接受任意的关键字参数。如果你试图在python中定义一个具有这种行为的类,你必须写def __init__(self, **kwds),...,除非你不能有一个名为self!的关键字参数。仅位置参数可以避免这个缺陷。
1.一些函数没有任何自然名称来分配它们的参数。以int构造函数为例。int(x="3")并不比int("3")更具可读性。仅位置参数允许将没有固有含义的名称视为实现细节,而不是模块的公共API的一部分。
PEP中还有一些细节,但这三点总结了该功能存在的一般原因。

vm0i2vca

vm0i2vca2#

一个原因是人们重命名了他们的函数参数,然后所有使用关键字的函数调用都不再正常工作。
例如,给定如下函数:

def pow(base: float, exponent: int) -> float:
   pass

你可以使用位置 * 或 * 关键字参数编写函数调用:

pow(4.5, 10)
pow(4.5, exponent=10)
pow(exponent=10, base=4.5)

如果参数随后被重命名:

def pow(base: float, exp: int) -> float:
   """
        CHANGE LOG OR VERSION HISTORY:
           `exponent` renamed to `exp`
   """   
   pass

那么引用旧参数名的调用将给予TypeError

pow(4.5, 10)  # OK
pow(4.5, exponent=10)  # TypeError
pow(exponent=10, base=4.5)  # TypeError

一个潜在的记忆是要求消费者只使用位置参数:

def pow(base: float, exponent: int, /) -> float:
    pass

相关问题