前言
函数式编程是初学者最先接触到的编程方法,下面主要介绍python中函数传参的几种不同的形式。
传参的基本形式
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def functionname(a, b):
print(a+b)
if __name__ == '__main__':
functionname(1, 2)
结果:
3
一般形式下的函数传参,实参和形参的数目必须要对应,否则会报错。
In [1]: def fun_name(a, b):
...: print(a+b)
In [2]: fun_name(1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-cfcdf16293c7> in <module>()
----> 1 fun_name(1)
TypeError: fun_name() takes exactly 2 arguments (1 given)
In [3]: fun_name(1, 2, 3)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-8f24614dfc73> in <module>()
----> 1 fun_name(1, 2, 3)
TypeError: fun_name() takes exactly 2 arguments (3 given)
缺省参数
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def functionname(a, b='china', cc=1111):
print("my name is %s"%a)
print("my address is %s"%b)
print("my phone is %d"%c)
if __name__ == '__main__':
name = raw_input('ENTER your name:')
# 示例使用的Python 2.7.5,python3使用input()
functionname(name)
结果
ENTER your name:zhang
my name is zhang
可以看到,函数的参数只传了一个name,b和c是用默认的参数代替,当然,如果对缺省参数传参的话,默认的参数会被覆盖。
需要注意的地方是,缺省参数一定要写在正常传参的后面,不然会报错non-default argument follows default argument,同时要注意传参的顺序。
In [4]: def fun_name(name='zhang', addr):
...: print(name)
...:
File "<ipython-input-4-ca7d69b85b54>", line 1
def fun_name(name='zhang', addr):
SyntaxError: non-default argument follows default argument
命名参数
命名参数也称之为关键字参数, 其仅针对函数的调用, 让调用者通过函数调用中的参数名字赋值来将实参映射到形参。可以以乱序的形式调用传参。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def functionname(a, b, c):
print("my name is %s"%a)
print("my address is %s"%b)
print("my phone is %s"%c)
if __name__ == '__main__':
name = raw_input('ENTER your name:')
addr = raw_input('ENTER your address:')
phone = raw_input('ENTER your phone numbers:')
# 示例使用的Python 2.7.5,python3使用input()
functionname(c=phone, b=addr, a=name )
# 注意这里没有按照顺序传参
结果
ENTER your name:zhang
ENTER your address:china
ENTER your phone numbers:1111
my name is zhang
my address is china
my phone is 1111
命名参数可以和缺省参数一块使用。在缺省参数的示例中,地址、电话号码已经有默认参数,假如只想更改默认的电话号码,不想更改地址,也必须传入三个参数,不可以缺省地址,因为参数是按照顺序传入的,而使用命名参数可以实现只传入两个参数。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def functionname(a, b='china', c='1111'):
print("my name is %s"%a)
print("my address is %s"%b)
print("my phone is %s"%c)
if __name__ == '__main__':
name = raw_input('ENTER your name:')
addr = raw_input('ENTER your address:')
phone = raw_input('ENTER your phone numbers:')
# 示例使用的Python 2.7.5,python3使用input()
functionname(c=phone, a=name )
# 缺省了地址
结果
ENTER your name:zhang
ENTER your address:nanjing
ENTER your phone numbers:33333
my name is zhang
my address is china
my phone is 33333
不定长参数
函数传参时形参和实参的数目要对应,缺省参数可以少传参,但要注意传参的顺序,那么假如函数传参的数量不确定,想要传入比预定数量多的参数,就要使用不定长参数。
def functionname(*args, **kwargs)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def functionname(a, *args):
print(a)
print(args)
# 多余的参数以元组形式保存
if __name__ == '__main__':
name = raw_input('ENTER your name:')
addr = raw_input('ENTER your address:')
phone = raw_input('ENTER your phone numbers:')
# 示例使用的Python 2.7.5,python3使用input()
functionname(name, addr, phone)
结果
ENTER your name:zhang
ENTER your address:china
ENTER your phone numbers:22222
zhang
('china', '22222')
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def functionname(a,**args):
print(a)
print(args)
# 多余参数保存为字典
if __name__ == '__main__':
Enter1 = raw_input('ENTER your name:')
Enter2 = raw_input('ENTER your address:')
Enter3 = raw_input('ENTER your phone numbers:')
# 示例使用的Python 2.7.5,python3使用input()
functionname(Enter1, addr=Enter2, phone=Enter3)
结果
functionname(Enter1, addr=Enter2, phone=Enter3)注意这里不是命名参数,而是多余参数以字典形式保存,这里传入的是字典的键值对。
ENTER your name:zhang
ENTER your address:china
ENTER your phone numbers:1111
zhang
{'phone': '1111', 'addr': 'china'}
假如没有多余的参数传入也不会报错,仅仅为空元组和空字典。
In [1]: def fun(a, *args, **kwargs):
...: print(a)
...: print(args)
...: print(kwargs)
...:
In [2]: fun(11)
11
()
{}
匿名函数lambda
匿名函数无须使用def关键字来进行声明。,因此也不用起函数名。
lambda函数可以接受任何数量的实参,但只会且仅返回一个表达式的值。
lambda函数不能包含有命令和多个表达式。
lambda函数拥有自己的命名空间,不能访问除自身参数列表之外的全局命名空间内的参数。
lambda最大的优势在于,可以不占用栈内存从而增加执行效率。
lambda函数的定义格式:
functionName = lambda [arg1[,arg2,…]]:expression
In [3]: n = lambda x,y:pow(x,y)
In [4]: type(n)
Out[4]: function
In [5]: n(3,2)
Out[5]: 9
In [6]: type(n(3,2))
Out[6]: int
多类型传入
其实不定长参数本质是将冗余的实参转换为Tuple数据类型后再传递给函数。下面的例子传递了一个Tuple类型实参给函数,和使用不定长参数效果是一样的。需要注意的是,不定长参数需要放到函数形参列表的后端,而Tuple类型形参可以随意放置。
# coding:utf-8
def fun_name(a, b):
print(a)
print(b)
if __name__ == '__main__':
name_tuple = ('a', 'b', 'c', 'd')
fun_name(name_tuple, 'e')
结果
('a', 'b', 'c', 'd')
e
当然也可以通过解包来限定只允许传入元组,*代表解包,迭代取元组的值。
# coding:utf-8
def fun_name(a, b, c ,d):
print(a+b+c+d)
if __name__ == '__main__':
name_tuple = ('a', 'b', 'c', 'd')
fun_name(*name_tuple)#解包
结果
abcd
当然也可以传入列表和字典。
# coding:utf-8
def fun_name(a, b, c, d):
print(a+b+c+d)
if __name__ == '__main__':
name_list = ['a', 'b', 'c', 'd']
fun_name(*name_list)
# coding:utf-8
def fun_name(a, b):
print(a)
for var in b:
print(b[var])
if __name__ == '__main__':
dic = {'name':"zhang", 'addr':'china', 'phone':"111"}
fun_name('a',dic)
结果
a
zhang
china
111
后言
增强型赋值语句
In [1]: Li = ['a', 'b']
In [2]: id(Li)
Out[2]: 30946944
In [3]: Li += ['c']
In [4]: id(Li)
Out[4]: 30946944
普通型赋值语句
In [1]: Li = ['a', 'b']
In [2]: id(Li)
Out[2]: 40478624
In [3]: Li = Li + ['c','d']
In [4]: id(Li)
Out[4]: 42890880