Discuss / Python / 可变参数、关键字参数和命名关键字参数测试

可变参数、关键字参数和命名关键字参数测试

Topic source

bzny虫

#1 Created at ... [Delete] [Delete and Lock User]

为了测试我对参数的理解,写了一段测试代码,必选和默认参数都简单就没弄了,就是后面几个:

def argss(*args,z3p,**kw):

    print(args)

    print(z3p)

    print(kw)

argss(*(2,3,4,5,6),z3p=233122,**{'z32':234,'b':8877})

1)发现当第三个关键字参数里,如果'z32'改成‘z3p',是报错的,提示z3p这个参数重复赋值,这个容易理解,一个参数不能同时赋两个值。

2)但是如果把第三个关键字参数前面的**变成*,也就是说从取完整字典变成取字典的键,则取出的键不再认为是关键字参数,而是会被归类到前面的可选参数*args,此时字典相当于一个序列,而且没有被z3p这个命名关键字参数隔断,哪怕在这个字典后面再加一个元组或者列表,一样会被读取,然后整个大列表会被赋值给*args.

3) 但如果把z3p的赋值形式变成**{'z3p':233122},则再次会报错,提示interable参数解压在关键字参数解压之后,也就是说字典解压赋值:**{}必须是放在最后面(可以有多个字典解压)。

4)所以python赋值的流程可以大致这样理解,假设对于一个包含了(a,b=3,*c,d,**e)这五种参数都齐全的函数,在实例化的过程中,其中单个值(比如单独的'c',3)和序列解压*(),*[],*{}可以互换顺序,位置赋值只按照从左到右的顺序赋值,剩下的都给可选参数;而x=xxxx和字典解压**{}可以互换顺序,其中存在命名关键字参数的赋值给命名关键字,剩下的都给关键字参数,找不到命名关键字要报错。

而这两大类互相之间则存在隔断,按照从左到右来看,其中单个值的优先级最低,x=xxxx和**{}都可以隔断它,单个值的赋值必须在任何一个x=xxx和**{}形式的赋值之前,举例来说:3,x=3和3,**{'a':3}是合法的,而x=3,3和**{},3是非法的;而**{}可以隔断序列解压*(),*[],*{},x=xxx则不能,举例来说:*(),x=3,**{}和x=3,*(),**{}都是合法的,但**{},*()则是非法的

真深入!


  • 1

Reply