python:函数形参列表中的斜杠(/)是什么意思?

python:函数形参列表中的斜杠(/)是什么意思?

1 前言

函数参数列表中的斜杠表示在它之前的形参都是仅限位置形参。 仅限位置形参没有可供外部使用的名称。 在调用接受仅限位置形参的函数时,参数将只根据其位置被映射到形参上。

官方文档参考:

https://docs.python.org/zh-cn/3/faq/programming.html#faq-positional-only-arguments

2 使用

参考python3.9,functools.partial部分源码:

class partial:
    """New function with partial application of the given arguments
    and keywords.
    """

    __slots__ = "func", "args", "keywords", "__dict__", "__weakref__"

    def __new__(cls, func, /, *args, **keywords):
        if not callable(func):
            raise TypeError("the first argument must be callable")

        if hasattr(func, "func"):
            args = func.args + args
            keywords = {**func.keywords, **keywords}
            func = func.func

        self = super(partial, cls).__new__(cls)

        self.func = func
        self.args = args
        self.keywords = keywords
        return self

    def __call__(self, /, *args, **keywords):
        keywords = {**self.keywords, **keywords}
        return self.func(*self.args, *args, **keywords)

可以看到如下的函数形参定义方式:

def __new__(cls, func, /, *args, **keywords)
def __call__(self, /, *args, **keywords)

结合前述,函数形参列表中的斜杠,表示:在斜杠之前的形参都是仅限位置形参。同时,函数形参列表中的斜杠不会占据参数解构的位置,也就是说,去掉斜杠的效果和带上斜杠的参数接收效果一致,区别仅是带上斜杠的参数列表,有限制其前面的参数,必须为位置形参

举例如下:

(2.1)内置函数divmod举个栗子:

源码如下所示:

def divmod(x, y): # known case of builtins.divmod
    """ Return the tuple (x//y, x%y).  Invariant: div*y + mod == x. """
    return (0, 0)

使用举例:

print(help(divmod))
print(divmod(11, 2))

结果如下,divmod返回的是元组,元组第一个值是x整除y的结果,第二个值是x除以y取余:

在这里插入图片描述

上述divmod函数,参数列表也带有斜杠,说明之前的参数x和y,必须为位置参数(也就是我们常用的*args),而不能是关键字参数(也就是我们常用的**kwargs):

print(divmod(x=11, y=1))

执行报错,TypeError: divmod() takes no keyword arguments:

在这里插入图片描述

同理,下述也是不行的:

print(divmod(11, y=1))

即便改换下述保留x和y位置参数,增加额外的关键字参数也是不行的:

print(divmod(11, 1, z=11))

执行依然报错:

在这里插入图片描述

(2.2)自定义函数举个栗子:

注意,当前演示代码,为python3.9版本:

第一个栗子:

def printC(x, /, *args, **kwargs):
    print(f"参数依次为: {x}, {args}, {kwargs}.")


printC(1, 2, 3, sum=10)

结果如下:

在这里插入图片描述

更换参数,执行下述代码:

printC(1, x=2, y=1, sum=10)

结果如下:

在这里插入图片描述

下述的写法是有问题的,因为斜杠parameter必须先于(precede)* parameter:

在这里插入图片描述

同理下述也是错误的:

在这里插入图片描述

下述也会报错(第一个位置必须是位置参数,不能使用关键字参数):

printC(x=2, y=1, sum=10)

执行报错:

在这里插入图片描述

第二个栗子:

自定义函数变例,斜杠前有含有默认值的参数:

def printC(x=1, /, y=2):
    print(f"参数依次为: {x}, {y}.")


printC(4, 5)
printC(6)
printC(y=9)

执行结果如下:

在这里插入图片描述

但是下述执行会抛错,因为第一个参数不能使用关键字参数x=?:

printC(x=9)

结果如下,报错TypeError: printC() got some positional-only arguments passed as keyword arguments: ‘x’:

在这里插入图片描述

第三个栗子:

斜杠前,有位置参数和含有默认值的参数:

def printC(z, x=1, /, y=2):
    print(f"参数依次为: {z}, {x}, {y}.")


printC(9, 8, 7)
printC(8, 7)
printC(7)

执行结果如下:

在这里插入图片描述

但是因为斜杠限制了前面的两个参数,都必须为位置参数,如下会抛出异常:

printC(7, x=8)

结果如下,依然抛出异常:

在这里插入图片描述

小结:

上述参数列表的解构赋值可知,参数列表中的斜杠是不会占据实际参数的,仅表明斜杠之前的形参必须为位置形参(斜杠前的形参,不论有无默认值,都必须使用位置参数,不可使用关键字参数)。如果参数列表中我们使用下划线,那么下划线是会占据参数的。

  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值