深度实践OpenStack:基于Python的OpenStack组件开发—3.5.2 函数参数
3.5.2 函数参数
还记得前面讲到的range函数吗?
range(10)
range(10,20)
range(20,30,2)
这3种调用方式都是合法的。这看起来就像是Java的方法重载,使用相同的函数名,参数个数不一样而已。下面是Java的代码:
def greeting(name):
pass
def greeting(name,age):
pass
def greeting(name,age,cla):
pass
但是这样的方式用在Python中是完全错误的。Python并不支持函数或者方法重载。那么,使用什么方式可以达到类似方法重载的功能?答案是参数。
在Python中,函数和方法的参数是一个相当重要的概念,可以说参数是函数和方法的灵魂。下面来看一下函数的参数有哪几种:
def greeting(name,age,cls="",*arg,**karg): statment
当一个函数或方法有多个参数时,使用“,”作为分隔符将参数分开,name和age这两个参数的性质是一致的,称为普通参数或者位置参数。这种参数在调用函数或者方法时必须传入,否则将会出现调用错误。
cls称为关键字参数或者默认参数,在进行函数或者方法调用时,这是一个可选的参数。
带两个“*”符号的参数称为关键字参数,和cls关键字参数不一样,指的是那些函数中存在,但是不知道具体名称的关键字参数。
带一个“*”号的参数称为位置参数,但这个位置参数和前面的位置参数不太一样,指的是那些函数中存在,但是不知道具体名称的位置参数。
需要注意,定义函数或者方法时,参数的排列顺序必须是位置参数、关键字参数、*参数和**参数,这个顺序不能变;同时位置参数是必须传入的。
如果把上边的函数或方法改成下边这种形式:
def greeting(*arg,**karg): statment
表示这个函数或方法可以接收任意个数的任意类型参数。这种类型的函数或者方法通常用于记录日志或者闭包函数及方法。这是比较重要的一种函数形式,在以后的讲解中将经常遇到类似的函数或者方法。注意,这里的参数指的是在函数或者方法进行定义时的参数,下面讲另一种模式的参数。
先来看这么一段代码:
def hello(name,age=10):
print "Hello,%d old friend named %s" %(age,name)
hello("awcloud",20)
hello("awcloud",age=20)
hello(name="awcloud",age=20)
hello(age=20, name="awcloud")
params_list = ["awcloud",20]
hello(*params_list)
params_dict = {"name":"awcloud","age":20}
hello(**params_dict)
上边的代码中定义了一个名为hello的函数,这个函数接收两个参数,即一个位置参数 name,一个关键字参数age。第一次调用的时候,完全采用和Java中的相同方式;第二次调用的时候,采用加上关键字参数名的方式;第三次调用的时候,采用加上所有参数名的方式;第四次调用时,采用加上参数名,并且顺序颠倒的方式;第五次调用的时候,采用*的方式;最后一次调用的时候,采用**的方式。
先说前面4种方式,强调一点,Python的函数和方法接收参数的时候,如果不指定参数名,默认是按照参数的位置依次接收的,但是如果指定了参数名,会完全按照参数名来接收参数。因此在Python中函数和方法的参数名相当重要。
现在看最后两种方式,在使用*的方式之前,构造了一个列表;在使用**的方式之前,构造了一个字典。hello(*params_list)这一句中的*和函数定义时不一样,不再表示位置参数,而是表示一个解包操作,表示将一个列表按照顺序解开;同理,**的方式也不再表示关键字参数,而是表示一个解包操作,表示将一个字典按照顺序解开。解开之后的操作是怎样进行的呢?
列表解开之后,按照位置参数的形式,依次向函数传递参数,因此,如果采用*的方式传递参数,那么在构造的列表中,参数的顺序一定要正确无误;字典被解开之后,按照关键字参数的形式向函数传递参数,因此,在使用**的方式传递参数时,必须保证字典的键一定要和函数中参数的名称对应起来。
- 点赞
- 收藏
- 关注作者
评论(0)