传递参数
参数是通过赋值来传递的。
1、参数的传递是通过自动将对象赋值给本地变量名来实现的。函数参数在实际中只是python赋值的另一个实例而已。因为引用是以指针的形式实现的,所有的参数实际上都是通过指针进行传递的。作为参数被传递的对象从来不自动拷贝。
2、在函数内部的参数名的赋值不会影响调用者。在函数运行时,在函数头部的参数名是一个新的、本地的变量名,这个变量名是在函数的本地作用域内的。函数参数名和调用者作用域中得变量名是没有别名的。
3、改变函数的可变对象参数的值也许会对调用者有影响。
Python的通过赋值进行传递的机制与C++的应用参数选项并不完全一样,但是在实际中,它与C语言的参数传递模型相当相似:
1、不可变参数“通过值”进行传递;
2、可变对象“通过指针”进行传递。
可变参数
当要使函数接受元祖或字典形式的参数的时候,有一种特殊的方法,它分别使用*和**前缀,这种方法在函数需要获取可变数量的参数的时候很有用。
>>> def powersum(power, *args):
... '''Return the sum of each argument
raised to specified power.'''
... total = 0
... for i in args:
... total += pow(i, power)
... return total
...
>>> powersum(2, 3, 4)
25
>>> powersum(2, 10)
100
由于在args变量前有*前缀,所有多余的函数参数都会作为一个元组存储在args中,如果使用的是**前缀,多余的参数则会被认为是一个字典的键值对。
>>>def func(a, *pargs):
... print (a, pargs)
...
>>>func(1,2,3)
1,(2,3)
>>>def func(a, **pargs):
... print (a, pargs)
...
>>>func(a=1, c=2, b=3)
1,{'c':2,'b':3}
如果参数表根本没有定义参数的名字的话,这个会是个空的。
也就是说如果一个函数的参数本来就是def fun(*args, **kwargs)的话,如果你在调用时没有使用名字指定参数名的话, kwargs 只能得到一个空的dict()
也就是说如果一个函数的参数本来就是def fun(*args, **kwargs)的话,如果你在调用时没有使用名字指定参数名的话, kwargs 只能得到一个空的dict()
输出结果
python中通常可以通过返回元组并将结果赋值给最初的调用者的参数变量名。
>>>def multiple(x,y):
x=2
y=[3,4]
return x,y
>>>X=1
>>>L=[1,2]
>>>X,L = multiple(X,L)
>>>X,L
(2,[3,4])
函数装饰器
函数装饰器提供了一种方法,替函数明确了特定的运算模式,也就是将函数包裹了另外一层,在另一函数的逻辑内实现。
从语法上讲,函数装饰器是它后边的函数的运行时的声明。函数装饰器是写成一行,就在定义函数或方法的def语句之前,而且由@符号、后面跟着所谓的元函数组成:也就是管理另一函数的函数。
没有return语句的函数
在python函数中,return语句是可选的,当一个函数没有精准的返回值的时候,函数在控制权从函数主体脱离时,函数就会退出。从技术上来讲,所有的函数都返回了一个值,如果没有提供return语句,函数将自动返回None对象。
>>>list = [1,2,3]
>>>list = list.append(4)
>>>print(list)
None