python函数参数类型与参数传递

参数传递

参数的传递是通过自动将对象赋值给本地变量名来实现的。在函数运行时,函数头部的参数名是一个新的、本地的变量名,这个变量名是在函数的本地作用域内存在。参数的传递本质上就是python赋值的另一个实例而已。

我们传递的参数分为可变类型和不可变类型。

不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。

可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响。python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。

def change(a,b):
    a = 2
    b[0] = 'hello'

x = 1
L = [1,2,3]
change(x,L)
print(x,L) #1 ['hello', 2, 3]

如上例所示,我们看到x作为不可变对象,函数调用并没有改变其值,而列表L的第一个值被改变。

如何避免修改可变对象呢?我们可以创建可变对象的拷贝,从而使其不可变。

参数类型

参数类型还可以分为必需参数、关键字类型、默认参数、不定长参数。

必需参数

必需参数须以正确的顺序传入函数,调用时的数量必需和声明时的一样。

def func(a,b,c):
    print(a,b,c)

func(1,2,3) #1,2,3

关键字参数

关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。

使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

def func(str):
    print(str)

func(str = 'hello') #hello

默认参数

调用函数时,如果没有传递参数,则会使用默认参数。

def func(name,age = 25):
    print("name:",name)
    print("age:",age)

func('li',30) #name:li age:30
func('feng') #name:feng age:25

不定长参数

你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。

对于不定长的参数,我们使用*和**两个符号来表示,两者都表示任意树木参数收集。其中*表示用元组的形式收集不匹配的位置参数,**表示用字典的形式收集不匹配的位置参数。

def func(a,*args):
    print(args)

def func1(**kargs):
    print(kargs)

def func2(a,*args,**kwargs):
    print(a,args,kwargs)

func(1,2,3,4) #(2,3,4)
func1(a=1,b=2) #{'a': 1, 'b': 2}
func2(1,2,3,x=4,y=5) #1 (2, 3) {'x': 4, 'y': 5}

上面是在函数定义的时候写的*和**形式,那反过来,如果*和**语法出现在函数调用中又会如何呢?他会解包参数的集合。

例如,我们在调用函数时能够使用*语法,在这种情况下,它与函数定义的意思相反,他会解包参数的集合,而不是创建参数的集合。例如我们可以通过一个元组给一个函数传递四个参数,并且让python将它们解包成不同的参数。在函数调用时,**会以键/值对的形式解包一个字典,使其成为独立的关键字参数。

def func(a,b,c,d):
    print(a,b,c,d)
args = (1,2,3,4)
func(*args)  #1,2,3,4

kargs = {'a':1,'b':2,'c':3,'d':4}
func(**kargs)   #1,2,3,4

https://zhuanlan.zhihu.com/p/33145623

http://www.runoob.com/python3/python3-function.html

你可能感兴趣的:(Python,*args,**kargs,不定长参数,函数参数类型)