以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。其中args和kwargs完全可以像其他参数一样自己命名,只是约定俗成的用*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)即可,无需加**。
2356

被折叠的 条评论
为什么被折叠?



