函数
1 创建函数与调用
def py(): //创建函数
print("人生苦短,我用python")
py() //调用函数
结果
人生苦短,我用python
1.1 lambda函数
python允许使用lambda关键字创建匿名函数。
lambda x,y : x * y
:左边是函数的参数,多个参数用逗号隔开。
:右边是返回值。
lambda语句会返回一个函数对象,使用前,赋值即可。
a = lambda x,y : x * y
print(a(4,5))
结果
20
1.2 函数文档
所谓函数文档,其实就是给函数写注释
def py():
"""
使用python // '''也可以
"""
print("人生苦短,我用python")
help(py)
结果
py()
使用python
2 函数参数
函数的括号内就是函数参数,多个参数用逗号隔开。
2.1 形参和实参
- 形参(parameter):创建函数时小括号里的参数
- 实参(argument):函数被调用过程中传递进来的参数
2.2 关键字参数
函数中有多个参数时,默认为顺序匹配,为防止搞乱参数位置,可以在函数调用的时候设置关键字参数,以避免此种情况的发生。
关键字参数其实就是在传入实参时指定形参的变量名
def test(name,thing):
print(name+'有'+thing)
test('无限手套','灭霸')
test(name='斯达克',thing='钢铁侠战衣')//这里采用了关键字参数
结果:
无限手套有灭霸
斯达克有钢铁侠战衣
2.3 默认参数
默认参数是在参数定义的过程中,为形参赋初值。当函数调用的时候,不传递实参,则默认使用形参的初始值代替。
def test(name='斯达克',thing='钢铁侠战衣'): //name和thing是默认参数
print(name+'有'+thing)
test()
结果:
斯达克有钢铁侠战衣
2.4 收集参数
收集参数也叫可变参数。当不清楚函数有多少个参数时可以使用,在参数前加上*即可。
def test(*listx):
print(listx)
test(1,2,3,4,5,'avengers')
结果:
(1, 2, 3, 4, 5, 'avengers')
当收集参数后,还有其它参数时,在调用函数时需用关键字参数来指定
def test(*hero,name):
print(*hero,'属于',name)
test('蜘蛛侠','黑豹','毒液',name='avengers') //使用关键字参数指定了name
结果:
蜘蛛侠 黑豹 毒液 属于 avengers
2.4.1 解包
要将元组或列表传入收集参数,调用函数时,要在实参前加上*,表示实参需要解包后使用。
def test(*hero):
print(len(hero))
print(hero)
name =['蜘蛛侠','黑豹','毒液']
test(name)
test(*name)
结果:
1
(['蜘蛛侠', '黑豹', '毒液'],)
3
('蜘蛛侠', '黑豹', '毒液')
2.5 函数返回值
return关键字用于返回函数的值,print是打印值不是返回值。不写renturn,python函数默认返回None。pyhton函数都是有返回值的。
def test():
print('avengers')
print(test()) //print打印函数的返回值,此时返回值为None
结果:
avengers
None
2.6 变量作用域
局部变量(local variable)
全局变量(global variable)
def discounts(price,rate):
new_price = price * rate
print('打折后的价格为:',new_price)
old_price = float(input('请输入原价: '))
rate2 = float(input('请输入折扣: '))
discounts(old_price,rate2)
结果:
请输入原价: 100
请输入折扣: 0.5
打折后的价格为: 50.0
如上程序:
- 函数内的参数price,rate和new_price属于局部变量。
- old_price、rate2属于全局变量。
函数里定义的参数和变量都是局部变量,出了函数后这些变量都是无效的。
原理:python在运行函数时,利用栈进行存储,函数执行完毕,函数内的数据都自动被删除。所以函数外无法访问函数内的局部变量。
全局变量都是在函数外部定义的,全局变量拥有更大的作用域,函数内也可以访问。
2.7 global关键字
# 尝试在函数内部修改全局变量的值
def test():
num = 10
print("修改变量后的值为:",num)
num = 100
test()
print("全局变量num的值为:",num)
结果:
修改变量后的值为: 10
全局变量num的值为: 100
在函数内部修改全局变量的值,python会创建一个名字与全局变量相同的局部变量以代替,所以全局变量的值不会被改变。
如果想要在函数内部修改全局变量就要使用global关键字。
def test():
global num //说明num为全局变量
num = 10
print("修改变量后的值为:",num)
num = 100
print("函数调用前num的值为:",num)
test()
print("执行函数后num的值为:",num)
结果:
函数调用前num的值为: 100
修改变量后的值为: 10
执行函数后num的值为: 10
2.8 内嵌函数
所谓内嵌函数即函数内部再定义函数
def fun1():
print("这是函数1")
def fun2():
print("这是函数2")
fun2()
fun1()
结果:
这是函数1
这是函数2
2.9 闭包
内嵌函数引用了外部作用域的变量(非全局变量),该内嵌函数则为闭包
def h1(x):
def h2(y):
return x * y
return h2
print(h1(2)(3)) //2赋值给了h1,3赋值给了h2
结果:
6
以下函数h2不是闭包,因为引用了全局变量num
def h1(x):
def h2(y):
return x * y * num
return h2
num = 4
print(h1(2)(3))
结果:
24
闭包只能引用外部函数的变量,如果修改就会报错。
def h1(x):
def h2():
x *= x
return x
return h2
print(h1(2)())
结果:
UnboundLocalError: local variable 'x' referenced before assignment
2.9.1 nonlocal关键字
闭包修改外部函数的变量,需要使用nonlocal关键字。就像global那样。
def h1(x):
def h2():
nonlocal x
x *= x
return x
return h2
print(h1(2)())
结果:
4
2.10 两个BIF filter( ) 和 map( )
2.10.1 filter( )
filter( ) 有两个参数。第一个参数可以是函数或None。如果是函数,则将第二个可迭代数据里的每一个元素作为函数的参数进行计算,把结果为Ture的返回值筛选出来。如果是None,则将第二个参中为Ture的值筛选出来。
listx = [1,2,3,0]
i = filter(None,listx)
print(list(i))
结果:
[1, 2, 3]
#要求输出10以内的奇数
print(list(filter(lambda x: x%2,range(10))))
结果:
[1, 3, 5, 7, 9]
2.10.2 map( )
map( )也有两个参数,一个函数和一个序列,将序列的每一个元素作为函数的参数进行运算,直到序列的每个元素都加工完毕,返回值为序列。
map(function, iterable, ...)
function -- 函数,有两个参数
iterable -- 一个或多个序列
Python 2.x 返回列表。
Python 3.x 返回迭代器。
#计算两个列表想家
print(list(map(lambda x,y: x+y,[1,2,3],[1,2,3])))
结果:
[2, 4, 6]