一.函数定义
1.函数创建
def 函数名(参数列表):
语句块
2.函数的语法说明:
(1)函数的命名规则和变量命名规则相同
(2)函数名是一个变量(不要轻易对其赋值)
(3)函数有自己的命名空间,在函数内部可以访问外部的变量,在外部不能访问函数内部的变量,函数内部变量执行完之后不会再存在了。
(4)函数的语句块部分不能为空,若为空,要填充pass语句
3.函数调用
调用说明:
1.函数调用是一个表达式
2.若没有return语句,函数执行完默认返回None。
3.关于return语句
(1)作用:结束当前函数的执行,返回到调用函数的地方,同时返回一个对象的引用关系。
使用示例:
def hello():
print('hello aaa')
print('hello bbb')
x=hello()
print(x)
#执行结果是
hello aaa
hello bbb
None
加入return语句
def hello():
print('hello aaa')
return
print('hello bbb')
x=hello()
print(x)
#执行结果是
hello aaa
None
加入return语句后,它下面的语句不会再执行,代表函数的功能已经完成了。
二.函数的参数传递
1.传递方式:
1.位置传参:实参的与形参的对应关系按位置来确定
2.序列传参:序列传参是在函数调用过程中,用 * 将序列拆解后,按位置传递方式进行匹配
def print_num(a,b,c):
print('a=',a)
print('b=',b)
print('c=',c)
s=[1,2,3]
print_num(*s)#将序列拆解后,依次传给形参a,b,c
*后面可以是元组,序列,字符串,字典,但是元素的个数一定要与形参数量一致,否则会出错,而且如果是字典的话,只会传递字典的键值
3.关键字传参:传参时,按着形参的名字给形参赋值
def print_num(a,b,c):
print('a=',a)
print('b=',b)
print('c=',c)
print_num(a=100,c=300,b=200)#按形参的名字匹配,不用考虑位置
4.字典关键字传参:实参为字典,用 ** 拆解字典后再进行关键字传参
def print_num(a,b,c):
print('a=',a)
print('b=',b)
print('c=',c)
s={'a':100,'b':200,'c':300}
print_num(**s)
说明:字典的键名必须和形参的名字一致,字典键名必须是字符串。
5.综合传参:函数的传参方式在确定形参能匹配到相应实参的情况下进行任意组合
规则:一般先是位置传参和序列传参,再是关键字传参和字典关键字传参
def print_num(a,b,c,d,e,f):
print('a=',a)
print('b=',b)
print('c=',c)
print('d=',d)
print('e=',e)
print('f=',f)
print_num(10,*[20,30],e=90,**{'d':50,'f':60})
#a=10,b=20,c=30,d=50,e=90,f=60
print_num(e=90,**{'d':50,'f':60},10,*[20,30])
#会出错,位置传参的参数不知道赋值给谁
2.函数的形参
1.函数的缺省参数:当实参的个数不够时,会用默认值绑定形参,就是缺省参数
示例:
def info(name,sex='不详',adress='不详'):
print("我叫",name,'我的性别是',sex,'我家住 ',adress)
info('王明','女')
#得到的结果是我叫王明,我的性别是女,我家住不详
规则:缺省参数必须从右至左依次存在,可以有0个,1个,2个…缺省参数的绑定对象存在于函数内,与函数的生命周期一致。
示例:
def fx(a,L=[]):
L.append(a)
print(L)
L=[1,2,3]
fx(5,L)#结果是[1,2,3,5]
fx(6,L)#结果是[1,2,3,5,6]
fx(1)#结果是[1]
fx(2)#结果是[2]
#以上结果反映了缺省参数的生命周期,调用完函数之后,将结果返回之后缺省参数就释放了,再次调用,依然是原来的默认值
2.函数的形参的定义方式:
(1)位置形参
(2)星号元组形参
def fx(*args):
print('实参个数是',len(args))
print('args值是',args)
fx(1,2,3)
fx("ABC")#返回的是一个元组,包含传递的所有元素,也可以这种形参可以传递任意个参数,类似于print函数,max函数
(3)命名关键字形参
语法:
def 函数名(*,命名关键字形参):
语句块
作用:所有的命名关键字形参都强制调用者采用关键字传参或字典关键字传参
例一:
def fx(a,*,b):
print('a= ',a)
print('b=',b)
fx(100,200)#出错
fx(100,b=200)#使用关键字传参
fx(100,**{'b':200})#字典关键字传参
例二:
def fx(a,*args,b):
print('a= ',a)
print('args= ',args)
print('b=',b)
fx(100,200,300)
#出错,100传给a,200,300传给*args,b没有值,所以也要用关键字传参
(4)双星号字典形参
语法:
def 函数名(**kwargs):
语句块
示例:
def fx(**kwargs):
print('关键字传参个数是',len(kwargs))
print('kwargs值是',kwargs)
fx(name='王明',age='16')#返回的是一个字典
fx(a=[1,2,3],b='16')#返回的是一个字典
(5)综合使用:
顺序是位置形参,星号元组形参,命名关键字形参,双星号字典形参
示例:
def fx(a,*args,c,**kwargs):
print(a,args,c,kwargs)
fx(100,200,300,*"ADF",**{'d':200,'e':300'},c=900)
#a=100,args=(200,300,,'A','D','F',),c=900,kwargs={'d':200,'e':300'}
三.函数变量
1.定义:函数名是一个变量,在创建时绑定了一个函数
2.应用:
(1)一个函数可以作为另外一个函数的参数(实参)传递
示例:
def f1():
print('f1 函数被调用')
def fx(fn):
print('fx 绑定的函数是',fn)
fn() #在函数内部调用fn
fx(f1)
#输出结果是 :
# fx 绑定的函数是 <function f1 at 0x000002CBD1BBC268>
# f1 函数被调用
(2)函数可以作为另外一个函数的返回值
示例:
def option():
op= input('请输入进行的操作:')
if op=='最大值' :
return max
elif op=='最小值':
return min
L=[1,2,3,4]
f=option() #根据输入的操作得到max 或 min
print(f(L))
四.函数嵌套
1.定义:def 语句可以写在一个函数内部,在外部函数执行时可以动态创建一个函数
示例:
def option(op):
if op=='求和' :
def my_sum(x,y):
return x+y
return my_sum
elif op=='最小值':
return min
f=option('求和') #得到my_sum函数
print(f(200,300))
五.全局变量和局部变量
1.局部变量:
(1)定义在函数内部的变量为局部变量(函数的形参也是)
(2)局部变量只能在函数内部使用
(3)局部变量在函数调用时才会创建,在函数调用之后自动销毁
(4)在函数内首次对变量赋值是创建一个局部变量,即使它可能和全局变量重名,再次为变量赋值是修改局部变量的绑定关系
(5)在函数内部的赋值语句不会对全局变量产生影响
2.全局变量:
(1)定义在函数外部,模块内部的变量成为全局变量
(2)全局变量所有函数可以直接访问
(3)函数内部不能直接修改全局变量的绑定关系
3.global 语句:实现在函数内部改变全局变量
示例:
x=100
def fx():
global x
x=200
fx()
print(x)#此时x=200
注意,不能先声明局部变量,然后再声明其为全局变量
x=100
def fx(x):
global x
x=200
fx(x)
print(x)#此时会出错
4.nonlocal 语句:声明变量是外部嵌套函数的作用域内的变量
示例:
def outter():
v=100
def inner():
nonlocal v
v=v+1
print("inner 里的v=",v)
inner()
print("调用inner 函数后,outter里的v=",v)
outter()
#得到结果为:
# inner 里的v= 101
# 调用inner 函数后,outter里的v= 101
六.作用域
1.定义:作用域也叫命名空间,是访问变量时查找变量名的范围空间
2.分类:(LEGB)
(1)局部作用域 (Local )
(2)外部嵌套函数作用域(Enclosing function locals)
(3)函数定义所在模块的作用域(Global)
(4)Python内置模块的作用域 (Builtin)
作用域关系:
示例:`
max=None
print(max(200,100))#会出错,因为max=None,而此时我们并没有改变python内置函数max,我们只是在G域内创建了一个max变量
del max #删除刚刚创建的max变量
print(max(200,100))#引用的是内建函数max
3.变量名的查找顺序:L<E<G<B
七.匿名函数表达式(Lambda表达式)
1.语法:
Lambda[形参1,...]:语句块
当这个表达式调用时,先执行冒号后面的表达式,返回表达式的结果,故只能包含一个表达式
2.作用:创建一个函数,不用提供函数名,函数使用更加灵活
示例:
my_sum=Lambda x,y:x+y
print(my_sum(1,2))
八.附加函数
(1) eval():把一个字符串当成一个表达式执行,
eval(source,globals=None,Local=None)globals,Local是变量的执行空间
print(eval('x+y'),{'x':1,'y':2}#得到3
print(eval('x+y'),{'x':1,'y':2},{'x':3,'y':4})#此时返回7,先在Locals里面找,再在Globals里面找,最后去内建函数里面找
print(eval('x+y'),{'x':1,'y':2},{'x':3})#返回的是5,因为x=3,y=2
(2)exec函数:把一个字符串当作程序来执行
exec(source,globals=None,Local=None),globals,Local是变量的执行空间
s="a=1;print('a=',a)"
exec(s)#得到的是 a=1,可见返回的是程序的执行结果
g={};L={}
while True:
text= input("请输入指令 :")
if text == "结束":
break
exec(text,g,L) #将创建的变量会存在L的字典里面
九.高阶函数
1.定义
满足下列函数中的一个函数即为高阶函数:
(1):函数接受一个或多个函数作为参数传入
(2):函数返回一个函数
2.分类
Python 内置的高阶函数:map,filter,sorted
(1)map函数:map(fn,*iterables)用函数对可迭代对象的每一个元素作为参数计算得到新的可迭代对象,当最短的一个可迭代对象不再提供数据时,此可迭代对象结束
for x in map(pow,[1,2,3],[1,2,3]):
print(x)#pow 需要两个参数,所以需要两个可迭代对象,输出1,4,27
for x in map(pow,[1,2,3],[1,2,3,4]):
print(x)#输出1,4,27 由于最短的迭代对象只有3个元素,所以有三个输出值
(2)filter函数:filter(fn,iterable),筛选可迭代对象 iterable中的数据,返回一个可迭代对象,此可迭代对象对 iterable进行筛选,函数fn对iterable 的每个元素求值,返回False时将此数据丢弃,返回True则保留
(3)sorted函数:将原可迭代对象排序,生成排序后的列表
sorted(iterable,key=None,reverse=False)#key是排序的规则,比如说是按字符串的长度,则key=len,这个规则可以是自己编写的函数。