Python学习-第五章-函数和lambda表达式
5.1 之前的基础知识不记录了
5.2 之前的基础知识不记录了
5.2.1 关键字参数
假设一个函数:
def createUser(name,age):
print(“姓名:”+name+”,年龄:”+age)
关键字参数:
按照参数名传入参数,例如:
createUser(name=“liuan”,age=30)
位置参数:
对照形参位置传入的参数,例如:
createUser(“liuan”,30)
如果需要混合使用关键字参数和位置参数,则须遵守:
必须将位置参数放在关键字参数前
5.2.2 参数默认值
示例:
def say_hi(name="liuan",message="hello world!"):
pass
Python规定,带默认值的参数放在形参列表最后
5.2.3 参数收集(个数可变的参数)
books此时可传入多个参数,并被处理为元祖传入
示例:
def test(a,*books):
print(books)
Python还可以收集关键字参数,会将关键字参数收集成字典。为了让Python能收集关键字参数,需要在参数前面添加两个星号。
示例:
def test(x,y,z,*books,**scores):
print(scores)
test(1,1,1,"xxx","yyy","zzz",xxx=222,yyy=333,zzz=444)
{'xxx':222,'yyy':333,'zzz':444}
5.2.4 逆向参数收集
在程序已有列表,元祖,字典等对象的情况下,把它们的元素拆开传给函数的参数
示例:
def test(name,*nums):
print("name参数:"+name)
print("nums参数:"+str(nums))
myTuple=(1,2,3,4)
test("liuan",*myTuple)
结果:
name参数:liuan
nums参数:(1, 2, 3, 4)
如果不使用逆向收集(不使用星号),整个元祖都将会作为一个参数,而不是将元祖的元素作为多个参数。
输出结果会是:
name参数:liuan
nums参数:((1, 2, 3, 4),)
也支持字典的逆向收集,字典将会以关键字参数的形式传入给函数的参数。
def bar(book,price,desc):
print(book,",这本书价格是:",price)
print('描述信息:',desc)
bar(book="钢铁是怎样炼成的",price=1000,desc="一本励志故事")
运行结果:
钢铁是怎样炼成的 ,这本书价格是: 1000 描述信息: 一本励志故事
或
dict1={"book":"ddd","price":222,"desc":"dddfeee"}
bar(**dict1)
运行结果:
ddd ,这本书价格是: 222 描述信息: dddfeee
5.2.5 函数的参数传递机制
- 所谓的值传递,就是将实际参数值的副本传入函数,而参数本身不会受到影响。
- 但是如果将参数包装成list,dict传入函数,则可以改变参数,因为函数复制的是指向集合的引用对象(指针)。
结论:
- 不管什么类型的参数,在Python函数中对参数直接使用“=”符号赋值是没用的,并不能改变参数。
- 如果需要让函数修改某些数据,则可以通过将这些数据包装成列表、字典等可变对象,然后将这些可变对象传入函数,在函数中通过列表、字典的方法修改它们,才能改变这些数据。
5.2.6 变量作用域
- 局部变量:
在函数中定义的变量,每个函数执行时,局部变量存在临时分配的栈内存中,运行结束,内存释放,局部变量销毁。 - 全局变量:
在函数外面,全局范围内定义的变量。可以在所有函数中被访问。
Python提供了3种工具函数来获取指定范围内的“变量字典”
- globals():返回全局范围内所有的全局变量的字典,可以通过globals[‘key’]来获取字典中key关键字对用的数据
- locals():返回当前局部范围内所有变量组成的变量字典,可以通过locals[‘key’]来获取字典中key关键字对用的数据
- vars(object):获取指定对象范围内所有变量组成的变量字典,如果不传入object参数,则作用与local()一致
示例:
name="liuan"
def test():
print(name)
name="xiayin"
test()
print(name)
报错:
UnboundLocalError: local variable 'name' referenced before assignment
原因:
Python语法规定:在函数内部对不存在的变量赋值时,默认为重新定义新的局部变量,会覆盖全局同名变量,所以上面程序报错。
以上代码若想无错运行,可作如下修改:
name="liuan"
def test():
print(globals('name'))
name="xiayin"
test()
print(name)
运行结果:
liuan liuan
或
name="liuan"
def test():
global name
print(name)
name="xiayin"
test()
print(name)
运行结果:
liuan xiayin
以上两种修改方案,结果不同。
5.3 局部函数
Python支持在全局函数内部定义局部函数:
def getMathFunc(type,nn):
def square(n):
return n * n
def cube(n):
return n * n * n
def factorial(n):
result=1
for index in range(2,n+1):
result *= index
return result
if type == 'square':
return square(nn)
elif type=='cube':
return cube(nn)
else:
return factorial(nn)
print(getMathFunc('square',3))
dict1={"type":"cube","nn":5}
print(getMathFunc(**dict1))
print(getMathFunc('factorial',9))
在函数中定义的局部函数中会出现一种情况,局部函数内的变量会遮蔽它所在的函数内的局部变量:
def foo():
name="liuan"
def bar():
print(name)
# 遮蔽了所在函数中的局部变量name
name="xiayin"
bar()
foo()
可改为:
def foo():
name="liuan"
def bar():
# 访问bar()所在函数内的局部变量name,而非bar()的局部变量name
nonlocal name
print(name)
# 遮蔽了所在函数中的局部变量name
name="xiayin"
bar()
foo()
提示:
nonlocal()和global()功能大致相似,区别为:
- global()用于声明访问全局变量
- nonlocal()用于声明访问当前函数所在函数内的局部变量
5.4 函数的高级内容
5.4.1 使用函数变量
def pow(base,exponent):
result=1
for i in range(1,exponent+1):
result *=base
return result
# 将函数pow赋值给变量my_fun
my_fun=pow
print(my_fun(3,4))
def area(width,height):
return width * height
# 将函数area赋值给变量my_fun
my_fun=area
print(my_fun(3,4))
以上示例代码说明,当函数赋值给变量后,也可通过该变量来调用函数。
5.4.2 使用函数作为函数形参
Python支持像使用其他参数一样使用函数参数
def map(data,fn):
result=[]
for e in data:
result.append(fn(e))
return result
# 定义平方根函数
def square(n):
return n * n
# 定义立方根函数
def cube(n):
return n * n * n
# 定义阶乘函数
def factorial(n):
result=1
for i in range(2,n+1):
result *= i
return result
data=[3,4,9,5,8]
print('原数据',data)
print('计算数组元素的平方')
print(map(data,square))
print('计算数组元素的立方')
print(map(data,cube))
print('计算数组元素的阶乘')
print(map(data,factorial))
5.4.3 使用函数作为返回值
Python还支持使用函数作为其他函数的返回值
def get_math_func(type):
# 定义平方根函数
def square(n):
return n * n
# 定义立方根函数
def cube(n):
return n * n * n
# 定义阶乘函数
def factorial(n):
result=1
for i in range(2,n+1):
result *= i
return result
if type == "square":
return square
elif type =="cube":
return cube
elif type =="factorial":
return factorial
print(get_math_func("factorial")(5))
print(get_math_func("cube")(100))
print(get_math_func("square")(10000))
5.5 局部函数与lambda表达式
5.5.1 使用lambda表达式代替局部函数
def get_math_func(type):
# 定义阶乘函数
def factorial(n):
result=1
for i in range(2,n+1):
result *= i
return result
if type == "square":
return lambda n:n * n
elif type =="cube":
return lambda n:n * n * n
elif type =="factorial":
return factorial
print(get_math_func("factorial")(5))
print(get_math_func("cube")(100))
print(get_math_func("square")(10000))
lambda表达式公式如下:
lambda [parameter_list] : 表达式
例如:
def add(x,y):
return x+y
可简化为:
lambda x,y:x+y
虽然lambda表达式只能创建简单的函数对象,但仍有两大优势:
- 对于单行函数,代码更为简洁
- 对于不需要多次复用的函数,用完之后立刻释放,提高了性能。