如何理解中的(*size, *,...)可变参数及keyword-only参数

以torch.ones()函数举例

torch.ones(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)

>>> torch.ones((2, 3, 4))
tensor([[[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]],

        [[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]]])
>>> torch.ones(2, 3, 4)
tensor([[[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]],

        [[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]]])

torch.ones(2, 3, 4) torch.ones((2, 3, 4)) 生成相同结果:torch.ones 的参数列表中,第一个参数是 *size(带星号的参数),这在 Python 中表示「可变位置参数」,作用是:允许函数接收任意数量的位置参数,并将这些参数打包成一个元组(tuple)

  • 当传入 torch.ones(2, 3, 4) 时,2, 3, 4 被视为三个独立的位置参数,*size 会将它们打包成元组 (2, 3, 4),作为张量的形状。
  • 当传入 torch.ones((2, 3, 4)) 时,(2, 3, 4) 是一个单独的元组参数,*size 会将这个元组「解包」为三个元素 2, 3, 4,最终同样被处理为形状元组 (2, 3, 4)

两种写法本质上都是向*size传递了相同的形状信息(2, 3, 4),最终生成的张量形状完全一致(2×3×4 的全 1 张量)。

在 Python 函数参数中,* 单独出现(如 torch.ones(*size, *, out=None, ...) 中的第二个 *)是「参数分隔符」,它的作用是强制其后的参数必须通过关键字参数(keyword argument)的形式传入,不能作为位置参数传入

keyword-only参数是Python3中新加入的特性,定义时有一个单独的*号,其实这也只是一种规定,*号看上去像是一个参数,其实它不占参数个数,是给解释器看的。规定*号后面的参数,能且只能用key=value的方式传入

**kwargs参数

def func(*args, **kwargs):
    print("type of args: ", type(args))
    print("args:", args)
    print("type of kwargs: ", type(kwargs))
    print("kwargs:", kwargs)
 
 
if __name__ == '__main__':
    func(1, 2, a=3, b=4)
# 输出
# type of args:  <class 'tuple'>
# args: (1, 2)
# type of kwargs:  <class 'dict'>
# kwargs: {'a': 3, 'b': 4}  

动态参数分两种,一个是*开头,例如*args,另一个是**开头,例如**kwargs。其中argskwargs完全可以像其他参数一样自己命名,只是约定俗成的用*args**kwargs,使用这两个IDE也会自动联想补全。args的类型是元组,调用函数时可以传入任意多的参数,这些参数会自动封装到args里,成为一个元组。kwargs的类型是字典,调用函数时可以传入任意多的自定义键值对参数,这些参数会自动封装到kwargs里,成为一个字典。

在函数里面args和*args,kwargs、*kwargs、**kwargs有什么区别?

def func(*args, **kwargs):
    print("*args:", *args)
    print("*kwargs:", *kwargs)
    print("**kwargs:", **kwargs)

if __name__ == '__main__':
    func(1, 2, a=3, b=4)

输出

*args: 1 2
*kwargs: a b

报错

TypeError                                 Traceback (most recent call last)
<ipython-input-17-5083c4849fe0> in <module>
      5 
      6 if __name__ == '__main__':
----> 7     func(1, 2, a=3, b=4)

<ipython-input-17-5083c4849fe0> in func(*args, **kwargs)
      2     print("*args:", *args)
      3     print("*kwargs:", *kwargs)
----> 4     print("**kwargs:", **kwargs)
      5 
      6 if __name__ == '__main__':

TypeError: 'a' is an invalid keyword argument for this function

*号在这里只是一个标识作用,是给解释器看的,相当于把元组和字典的键的内容取出来
** 在函数调用中是 “字典解包” 操作,作用是将字典的键值对解包为关键字参数(格式为 key=value
比如:

d = {'a':3, 'b':4}
print(**d)  # 等价于 print(a=3, b=4)

** kwargs 解包后是 a=3, b=4,这些并非print 函数支持的关键字参数,因此会报错
若要打印 kwargs 字典的内容,直接使用kwargs即可(无需 **):print("kwargs:", kwargs) # 直接打印字典 {'a':3, 'b':4}

  • ** 的作用是 “解包字典为关键字参数”,仅用于函数调用时传递符合参数要求的键值对。
  • 打印字典内容时,直接使用字典变量(kwargs)即可,无需加 **
IDL> .compile -v 'D:\Harris\IDLwork\Default\binary.pro' 'jpg', 'jpeg': begin ^ % Syntax error. At: D:\Harris\IDLwork\Default\binary.pro, Line 12 read_jpeg, filename, image, /quiet ^ % Syntax error. At: D:\Harris\IDLwork\Default\binary.pro, Line 14 if size(image, /n_dimensions) eq 3 then begin ^ % Syntax error. At: D:\Harris\IDLwork\Default\binary.pro, Line 16 print, '检测到RGB图像,转换为灰度...' ^ % Syntax error. At: D:\Harris\IDLwork\Default\binary.pro, Line 17 image = reform(0.299*image[0,*,*] + 0.587*image[1,*,*] + 0.114*image[2,*,*]) ^ % Syntax error. At: D:\Harris\IDLwork\Default\binary.pro, Line 18 endif ^ % Type of end does not match statement (ENDCASE expected). At: D:\Harris\IDLwork\Default\binary.pro, Line 19 % 6 Compilation error(s) in module DISPLAY_IMAGE_STATS. 'tif', 'tiff': begin ^ % Syntax error. At: D:\Harris\IDLwork\Default\binary.pro, Line 21 % 1 Compilation error(s) in module $MAIN$. else: begin ^ % Syntax error. At: D:\Harris\IDLwork\Default\binary.pro, Line 30 % 1 Compilation error(s) in module $MAIN$. endcase ^ % Syntax error. At: D:\Harris\IDLwork\Default\binary.pro, Line 34 wait, /key ^ % Keyword parameters not allowed in call. At: D:\Harris\IDLwork\Default\binary.pro, Line 119 wait, /key ^ % WAIT: Incorrect number of arguments. At: D:\Harris\IDLwork\Default\binary.pro, Line 119 % 3 Compilation error(s) in module $MAIN$. pro image_stats_example ^ % Procedure header must appear first and only once: IMAGE_STATS_EXAMPLE At: D:\Harris\IDLwork\Default\binary.pro, Line 124 % 1 Compilation error(s) in module $MAIN$. pro create_gray_image, filename, cols, rows ^ % Procedure header must appear first and only once: CREATE_GRAY_IMAGE At: D:\Harris\IDLwork\Default\binary.pro, Line 147 'jpg', 'jpeg': write_jpeg, filename, image, quality=90 ^ % Syntax error. At: D:\Harris\IDLwork\Default\binary.pro, Line 170 'tif', 'tiff': write_tiff, filename, image, /gray ^ % Syntax error. At: D:\Harris\IDLwork\Default\binary.pro, Line 171 % 3 Compilation error(s) in module $MAIN$. pro binary ^ % Procedure header must appear first and only once: BINARY At: D:\Harris\IDLwork\Default\binary.pro, Line 177 % 1 Compilation error(s) in module $MAIN$.
06-14
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值