python中 *args和**kwargs

博客介绍了*args和**kwargs的使用。当参数个数不确定时,用(*args, **kwargs)适应变参数和命名参数,args处理位置参数,kwargs处理关键字参数。*和**有解包功能,还补充了isinstance()函数和OrderedDict的相关知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参数个数可变

为什么我们会使用*args和**kwargs表示输入的参数呢?因为当参数个数不确定的时候,不能够使用基于位置的参数表示方式,我们会使用(*args, **kwargs)来自动适应变参数和命名参数。这意味着,我们想往函数中输入多少个参数都行,分别以元组形式,字典形式传递参数。

def test(*args,**kwargs):
    print(type(args),args)
    print(type(kwargs),kwargs)
    
test("test",y='test2')
<class 'tuple'> ('test',)
<class 'dict'> {'y': 'test2'}

从上面的例子可以看出,args负责位置参数,并且将参数放到了元组tuple中。而kwargs(key word arguments)负责关键字参数,将参数放到了字典(dict)中。

名称不唯一

*args和 **kwargs变量前面的*是必须的。args和kwargs名称是一个常用的书写方式。换成*v和**vs或者别的都可以。

其中**kwargs传入的参数必须形式上有key-value才行。例如

a=(1,2,3)
b=[1,2,3]
c={1,2,3}
d={1:1,2:2,3:3}
test(a)
<class 'tuple'> ((1, 2, 3),)
<class 'dict'> {}
test(b)
<class 'tuple'> ([1, 2, 3],)
<class 'dict'> {}
test(c)
<class 'tuple'> ({1, 2, 3},)
<class 'dict'> {}
test(d)
<class 'tuple'> ({1: 1, 2: 2, 3: 3},)
<class 'dict'> {}
test(a,b,c,d)
<class 'tuple'> ((1, 2, 3), [1, 2, 3], {1, 2, 3}, {1: 1, 2: 2, 3: 3})
<class 'dict'> {}
test(a,y=b,z=c)
<class 'tuple'> ((1, 2, 3),)
<class 'dict'> {'y': [1, 2, 3], 'z': {1, 2, 3}}

此外,*和** 有解包的功能

*和**还可用于列表、元组、字典的解包,但是*后的参数必须是一个迭代器。例如

In [7]: a=(1,2,3)                                                               

In [8]: print(a)                                                                
(1, 2, 3)

In [9]: print(*a)                                                               
1 2 3

In [10]: b={'1':'name', '2':'age'}                                              

In [11]: print(*b)                                                              
1 2

使用

例如,当使用*args接受参数的时候,会遇到判断,并对输入参数进行处理。下面是一个处理的例子。

from collections import OrderedDict
#**省略**
def __init__(self, *args):
    super(Sequential, self).__init__()
    if len(args) == 1 and isinstance(args[0], OrderedDict):
        for key, module in args[0].items():
            self.add_module(key, module)
    else:
        for idx, module in enumerate(args):
            self.add_module(str(idx), module)
#**省略**

# Example of using Sequential with OrderedDict
model = nn.Sequential(OrderedDict([
          ('conv1', nn.Conv2d(1,20,5)),
          ('relu1', nn.ReLU()),
          ('conv2', nn.Conv2d(20,64,5)),
          ('relu2', nn.ReLU())
        ]))

补充

isinstance()

isinstance() 函数来判断一个对象是否是一个已知的类型。与type对比:isinstance()会认为子类是父类类型,考虑继承关系。type()不会认为子类是一种父类类型,不考虑继承关系。

class A:
    pass
 
class B(A):
    pass
 
isinstance(A(), A)    # returns True
type(A()) == A        # returns True
isinstance(B(), A)    # returns True
isinstance(B,A)       # returns False
type(B()) == A        # returns False
OrderedDict

字典的子类OrderedDict,保存了被添加的顺序。
官网OrderedDict
常规的 dict 被设计为非常擅长映射操作。 跟踪插入顺序是次要的。OrderedDict 旨在擅长重新排序操作。 空间效率、迭代速度和更新操作的性能是次要的。

算法上, OrderedDict 可以比 dict 更好地处理频繁的重新排序操作。 这使其适用于跟踪最近的访问(例如在 LRU cache 中)。
对于 OrderedDict ,相等操作检查匹配顺序。
OrderedDict 类的 popitem() 方法有不同的签名。它接受一个可选参数来指定弹出哪个元素。
OrderedDict 类有一个 move_to_end() 方法,可以有效地将元素移动到任一端。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值