python中args的用法,python中args什么意思
Python参数传递*args和**kwargs和*其实真正的Python参数传递语法是*和* *。*args和**kwargs只是一种常规的编程实践。我们也可以写* vars和* * kvars。就像其他正则变量的命名一样,args和kwargs只是约定俗成的名字。
*args和**kwargs一般在定义函数时使用。两者的意义都是允许定义的函数接受任意数量的参数。也就是说,在函数被调用之前,我们不知道也不限制函数未来可以接收的参数个数。在这种情况下,我们可以使用*args和**kwargs。
接下来我们分别分析*args和**kwargs在函数定义(即在参数列表中)和函数调用中的用法。
函数定义*args *args中的*和* *(即函数参数列表中的*和* *)用于表示函数接收一个变长非关键字的参数列表作为其输入。我们通过一个例子来体验一下参数列表中*args的用法:
Test _ args (normal _ arg,* args):print( normal arg: normal _ arg)print(type(args))for args in args:print( another arg through * args: arg)test _ args( normal , python , c
normal arg:normal class tuple another arg through * args:Python another arg through * args:can other arg through * args:c * * kwargs在定义函数时意味着函数接收一个变长的关键字参数字典作为其输入。* *当我们需要函数接收参数带关键字作为输入时,应该使用kwargs。通过下面的例子可以进一步了解**kwargs。
Test _ kwargs (* * kwargs):如果kwargs不为none: print (type (kwargs)) for key,value in kwargs . items():print( { }={ } 。format (key,value))test _ kwargs(name= python ,
Class dictname=pythonvalue=5如何处理关键字参数中的未知数?虽然参数表中的*和* *允许我们接收任意数量的参数变量,但我们在设计函数时肯定不处理任何参数。函数的调用方要知道*args和**kwargs中需要传什么参数,可以传什么参数(比如深度学习模型中模型结构的设置,比如模型深度等。)并且我们在函数体中处理这些参数。
但是,我们不知道调用者在调用时会传递什么,哪些应该在调用时使用默认值。这里笔者参考的是timm可视化库对ViT的实现。
在_create_vision_trainsformer函数中,我们只需要处理与我们相关的传入参数:
def _ create _ Vision _ Transformer(variant,pretrained=False,default_cfg=None,* * kwargs):default _ CFG=default _ CFG或default _ CFG[variant]if kwargs . get( features _ only ,None):raise runtime error( features _ only不适用于Vision Transformer模型。)#请注意,如果repr_size不为None且num_classes不为num_classes,则此额外代码将支持对21k预训练模型的repr大小的处理。=default_num_classes: #如果微调,则移除制图表达图层。这可能并不总是想要的行动,#但我觉得比什么都不做默认微调。也许是更好的界面?_logger.warning(移除制图表达图层以进行微调。)repr _ size=None model=build _ model _ with _ CFG(vision transformer,variant,pretrained,default_cfg=default_cfg,representation_size=repr_size,Pre trained _ filter _ fn=check point _ filter _ fn,Pre-trained _ custom _ load= npz in default _ CFG[ URL ],* * kwargs)返回模型。如您所见,我们传入的kwargs是一个字典。这里,使用字典的get和pop方法来处理它。
Python的get和pop方法pop dict.pop(key[,default])删除字典给定的键及其对应的值,返回值就是删除的值。如果该键不存在,它将返回由default参数指定的默认值。
get dict.get(key,default=None)函数返回指定键的值,如果该键不存在,则返回由default参数指定的默认值。
通过这两个方法,我们可以在kwargs中没有传入参数时使用默认值,在有指定参数时使用传入的值。
当调用一个函数时,在*和* *列表前添加一个星号用于将列表解包为两个独立的参数,这两个参数传递给函数,
在字典前面加两个星号就是把字典解绑成独立的元素作为形式参数。
如果我们有加法函数add():
DEF (A,B): *调用return A B函数时。我们可以这样调用:先构造一个列表,然后用*把列表解包,把值作为参数一个一个传入函数的参数列表:
Data _ list=[1,2]print(add(* data _ list))# Output:3相当于
Print(add(1,2))我们甚至可以在*直接展开列表后打印出参数序列:
Print(*data_list)# output: 1 2 * *调用函数时。我们也可以用字典的形式调用:构造一个字典,把键名作为要调用的函数的参数名,把值作为我们要传递的参数:
Data _ dict={a: 1, b :2 } print(add(* * data _ dict))# output:3相当于:
Print(add(a=1,b=2))注意,我们这里构造的字典的键名必须与函数参数表中的参数名相对应,否则会报错,比如
Data _ dict={a: 1, c: 2} print (add (* * data _ dict))相当于:
Print(data(a=1,c=2))将报告一个错误:
类型错误:add()得到了意外的关键字实参‘c’两种用法的统一理解以关键字实参**kwargs为例。让我们这样来考虑:
我们提到对于一个字典dict={a: 1, b: 2},给它加一个* *号就相当于把里面的元素解包了,也就是说,**dict相当于a=1,b=2,这正好符合我们调用函数传递参数时的写法。
而当**kwargs在中间参数表时,我们传入A=1,B=2。我们来看一下,正好对应了我们上面的**dict(只是名字不一样,开头提到也无妨)。那么去掉* *符号后,kwargs就相当于我们上面的dict,是一个字典:{a: 1。这就解释了为什么在上面我们介绍函数定义的**kwargs的例子中,type(kwargs)是dict,而在函数体中,我们也是通过调用dictionary类的方法(比如items,pop,get)来处理。
参考:
https://www.jianshu.com/p/be92113116c8
https://github.com/rwightman/pytorch-image-models
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。