函数传参
不可变传复制,可变传指针地址
一类不可以改变:整型、浮点型、字符串、Tuple。传递不可变类型,传递副本给函数,函数内操作不影响原始值
一类可以改变,列表 字典表。传递可变类型,传递地址引用,函数内操作可能影响原始值。如果不想改变可以传递副本。
参数匹配
- 参数匹配:默认位置匹配
- 参数匹配:顺序打乱,按名称匹配
- 参数匹配:有默认值可省略传值
def func1(a,b,c):
print(a,b,c)
func1(1,2,3) #1 2 3
def func2(a, b, c):
print(a,b,c)
func2(c=1,b=2,a=3) # 3 2 1
def func3(a,b=2,c=3):
print(a,b,c)
func3(5) #5 2 3
参数的收集和分配(装包和解包)
解包
a = (1, 2, 3, 4, 5, 6)
b = [2, 3, 4, 5, 5, 6]
c = {"name": 'zhang', "age": 2}
print(*a) #1 2 3 4 5 6
print(*b) #2 3 4 5 5 6
print(*c) #name age
一个星号*的作用
装包
形参前面的星号将提供的所有值都放在一个元组tuple中,也就是将这些值都收集起来
def avg1(*scores): # 没有做除数为零的异常处理
return sum(scores) // len(scores)
print(avg1(90,100,80))
def avg2(score, *scores): # 函数定义时要求至少一个数字,避免除数为零
return (score + sum(scores)) // (1 + len(scores))
print(avg2(0))
def avg3(*scores):
print(type(scores)) # <class 'tuple'>
if scores == (): # 根据可以看出,参数被收集为元组
return
return sum(scores) // len(scores)
print(avg3())
混合参数
与赋值一样,带星号的参数也可以放在其他位置(而不是最后),但不同的是,在这种情况下需要做些额外的工作:使用关键字来指定后续参数
def fun1(x,*y,z):
print(x,y,z)
fun1(1,2,3,4,5,z=6) # 1 (2, 3, 4, 5) 6
def fun2(x,*y):
print(x,y)
fun2(1,2,3,4,5,6) # 1 (2, 3, 4, 5, 6)
两个星号**收集参数
Python 中函数参数带**的话,将会收集关键字参数到一个字典中;
- 如果传递整个list,形参与实参都需要*
>>> def fun(x,y,z=3,*pospar,**keypar):
... print(x,y,z)
... print(pospar)
... print(keypar)
...
>>> fun(1,2,4,4,5,6,a = 11,b = 12,c = 13)
1 2 4
(4, 5, 6)
{'a': 11, 'b': 12, 'c': 13}
>>> fun(1,2)
1 2 3
()
{}
>>>fun(1,2,4)
1 2 4
()
{}
如果一个一个传递值,形参用**
如果整体传递值对,形参与实参都用**即先解包再装包
def display(**employee):
print(employee)
display(name="huang",age="23",job="Dev")
emp = {"name":"huang","age":"23","job":"Dev"}
display(**emp)
注意
在传入参数时,可变参数(*)之前不能指定参数名
def myfun(a, *b):
print(a)
print(b)
myfun(a=1,2,3,4)
myfun(a=1,2,3,4)
^
SyntaxError: positional argument follows keyword argument
2.函数传入实参时,可变参数(*)之后的参数必须指定参数名,否则就会被归到可变参数之中
def myfun(a, *b, c=None):
print(a)
print(b)
print(c)
myfun(1,2,3,c=4)
1
(2, 3)
4
3.一个函数想要使用时必须明确指定参数名,可以将所有参数都放在可变参数之后
def myfun(*, a, b):
print(a)
print(b)
myfun(a=1, b=2)
1
2
4.关键字参数都只能作为最后一个参数,前面的参数按照位置赋值还是名称赋值都可以
def myfun(a, *b, c, **d):
print(a)
print(b)
print(c)
print(d)
myfun(1, 2, w=6, c=3, d=4, e=5) # 记住可变参数(*)之前不能指定参数名
1
(2,)
3
{'w': 6, 'd': 4, 'e': 5}
Lambda表达式
什么是Lambad表达式
简单理解:一个匿名函数,省略了定义函数时def 名称 括号 冒号 return
lambda用来编写简单的函数,而def用来处理更强大的任务。
下面一个例子:
def holle(name):
print(name)
holle("普通例子")
f = lambda name : print(name)
f('lambda表达式例子')
f1 = lambda x, y : print(x+y)
f1([1,2,3],[2,3,4])
# 直接传参
(lambda x, y : print(x+y))([1,2,3],[2,3,4])
lambda用来编写跳转表(jump table)行为的列表或者字典
L = [lambda x: x+2, lambda x: x*2, lambda x: x**2]
print "L=", L[0](1), L[1](2), L[2](3)
#L = 3 4 9
D = {"d1": lambda x: x**1, "d2": lambda x: x**2, "d3": lambda x: x**3 }
print "D=", D["d1"](2), D["d2"](2), D["d3"](2)
使用lambda表达式,简洁
while True:
name = input("请输入您的名字:\n")
if name == 'stop':
break
language = input('请选择语言:\n c=>中文\n e=>英文\n j=>日语')
if language == "c":
action = lambda name : print("你好", name)
elif language == "e":
action = lambda name : print("holle", name )
else:
action = lambda name : print("nihao", name)
action(name) # action统一接收执行内容,但是此时函数并没有执行