函数小结
1.函数的定义:
1.1函数名存放函数地址,存放地址的叫做对象,因此函数名称为函数对象。
函数的定义:
def function_name(*args,**kwargs):
code1函数体
return 返回值
def为函数的定义关键字
function_name为函数名
(*args,**kwargs)为函数的形参
code1函数体
return 返回值,将函数的执行效果返回给外界使用
函数的参数:
形参:args,**kwargs为形式参数,等待外部实参传值(形参是实参的值拷贝)
实参:实际的值向args**kwargs传值(外界调用函数传入的值,拥有实际值)
实参:
位置实参:一定按照位置给形参传值
关键字实参:必须明确形参名字与值,为形参传值可以不按照位置传值
注:混用
关键字实参必须出现在位置实参之后。
def func(x,y):
print(x,y)
func(x=10,10)
SyntaxError: positional argument follows keyword argument
错误: 位置参数跟随关键字参数
关键字参数给形参传值可以不按照顺序
def func(x,y):
print(x,y)
func(y=10,x=10)
10 10
形参
位置形参:可以有位置实参传值,也可以有位置实参传值
默认形参:可以由位置实参与关键字实参传值,也可以不传值
位置形参与默认形参同在,默认形参必须在位置参数后面
def func(x=10,y):
print(x,y)
func(y=10,x=10)
SyntaxError: non-default argument follows default argument
错误:非默认的参数跟在默认参数之后,默认参数在位置参数前报错
可变长形参:*args用于接收位置参数未接收的值
def func(x,y,*args):
print(x,y,args)
func(10,10,10,20)
打印值 10 10 (10, 20)
def func(x,y,*args):
print(x,y,*args)
func(10,10,10,20)
打印值 10 10 10 20
*args散列打印
args本质是一个元组
def f(*args):
print(args)
print(*args)
list1=[1,2,3]
f(list1)
因此打印值为([1, 2, 3],) 为单个元素的元组
[1,2,3]打印原意多个值则打印多个值,单个列表则打印单个列表
定义函数以为分割位置形参,默认位置形参,可变长位置形参,关键字形参,关键字默认形参,可变长关键字形参*
def func(a, b=10, *, c, d=100, e, **kwargs):
print(a,b,c,d,e,kwargs)
print(*kwarg)
func(1,2,c=10,e=100,x=200,y=300)
1 2 10 100 100 {'x': 200, 'y': 300}
x,y *kwarg为字典的key
注:*只是起到分割的作用
dic={'name':'wy','age':18}
def f2(**kwargs):
print(*kwargs)
print(kwargs)
f2(**dic)
打印为:
name age
{'name': 'wy', 'age': 18}
定义函数:位置形参>默认形参>可变长形参>关键字形参>可变长关键字形参
函数名可以作为变量被引用:
def fun()
print("hello")
fuck=fun#将fun函数对象传给fuck
def trans(fuck):
fuck()
函数名作为参数传递给函数
可以作为函数的返回值
def func():
return func
可以作为容器的元素:
dic={"fun":func}
dic['fun']()则表示执行func函数
名称空间:名称空间是变量名与变量地址的对应关系,本质是一个__dict__记录的是名字与值的对应关系
名称空间是由文件,函数,类产生
文件的是全局名称空间,函数以及变量名等
函数产生的局部名称空间,函数的变量传入值等
内置名称空间,系统级的随着解释器的启动而产生,放着内置的函数和异常
Local(局部命名空间)在函数被调用时才被创建,但函数返回结果或抛出异常时被删除。(每一个递归函数都拥有自己的命名空间)。
Global(全局命名空间)在模块被加载时创建,通常一直保留直到python解释器退出。
Built-in(内建命名空间)在python解释器启动时创建,一直保留直到解释器退出
作用域:名字的作用范围:或者成为变量的可见性
【生命周期】
Local(局部命名空间)在函数被调用时才被创建,但函数返回结果或抛出异常时被删除。(每一个递归函数都拥有自己的命名空间)。
Global(全局命名空间)在模块被加载时创建,通常一直保留直到python解释器退出。
Built-in(内建命名空间)在python解释器启动时创建,一直保留直到解释器退出。
各命名空间创建顺序:python解释器启动 ->创建内建命名空间 -> 加载模块 -> 创建全局命名空间 ->函数被调用 ->创建局部命名空间
各命名空间销毁顺序:函数调用结束 -> 销毁函数对应的局部命名空间 -> python虚拟机(解释器)退出 ->销毁全局命名空间 ->销毁内建命名空间
python解释器加载阶段会创建出内建命名空间、模块的全局命名空间,局部命名空间是在运行阶段函数被调用时动态创建出来的,函数调用结束动态的销毁的。
闭包:函数的嵌套定义,闭包是内部函数inner
函数嵌套函数:
def func():
def inner():
inner()
return inner
闭包是inner
装饰器:闭包的一种实际应用
装饰器格式,装饰函数传入装饰函数(func),inner是装饰后的函数,并将装饰的函数名返回出去,且在inner函数中必须执行func函数,且为其增加新的功能。
装饰器是保持开放封闭原则:
不改变原来函数的源代码,不改变函数的调用方式
def outer(func):
def inner(*args,**kwargs):
函数前加功能
if 条件1:
res=func()
return inner
登录验证的装饰器,对其他函数的装饰,即如果登录了则执行该函数,若没执行登录则返回登录
def authlogin(type)
def outer(func):
def wrapper(*args,**kwargs):
if type=='admin':
if src.user_info["name"]:
res=func(*args,**kwargs)
return res
else:
src.login()
return wrapper
return outer
@auth_login(type)# function=auth_login(func) auth_login(func)返回的是inner
def function():
print("hh")
def check(参数1):
def outter(func):
def inner(*args,**kwargs):
res=func()
return res
return inner
return outer
#@check(hello) @ check(hello)=执行了check返回outer @outer
##@outer func=outer(fun)
@check(hello)
def f():
print("hello")
def iwapper(fun):
def inner(ROLE):
if ROLE == "boss":
print("====身法验证通过====")
fun()
else:
print("====不好意思,您不是老板====")
return inner
def test1():
print("====给员工加薪了!====")
def test2():
print("====出新版本,杀一个程序员祭天!====")
三元表达式:
x if x>y else y
判断大小值
一般配置匿名函数与推倒式使用
列表推到式:
[i for i in range(1,9)]
字典推到式:
{i:"奇数" if i %2==1 else "偶数" for i in (1,11)}
{1: '奇数', 2: '偶数', 3: '奇数', 4: '偶数', 5: '奇数', 6: '偶数', 7: '奇数', 8: '偶数', 9: '奇数', 10: '偶数'}
内置函数:
dic= {"wy":18000,"hh":17000}
max(dic,key=lambda k:dic[k])
匿名函数:
lambda x:y
x为参数 y为返回值
ret = filter(lambda x: x > 22, [11, 22, 33, 44, 55, 66, 77])
dic= {"wy":18000,"hh":17000}
max(dic,key=lambda k:dic[k])
递归:
函数的回溯,自己调用自己,回溯(回溯有条件)递推(递推开始回溯到结束点)
如求阶乘:
def func(x):
if x==1:#为出口条件回溯寻找答案的过程
return 1
elif x>1:
return func(x-1)x##,递推是推出答案的过程
递归与迭代区别与联系
1、递归与迭代:
递归和迭代都是循环的一种。简单地说,递归是重复调用函数自身实现循环。迭代是函数内某段代码实现循环,而迭代与普通循环的区别是:循环代码中参与运算的变量同时是保存结果的变量,当前保存的结果作为下一次循环计算的初始值。
递归循环中,遇到满足终止条件的情况时逐层返回来结束。迭代则使用计数器结束循环。当然很多情况都是多种循环混合采用,这要根据具体需求。
具体来讲:
递归的基本概念:程序调用自身的编程技巧称为递归,是函数自己调用自己. 一个函数在其定义中直接或间接调用自身的一种方法,它通常把一个大型的复杂的问题转化为一个与原问题相似的规模较小的问题来解决,可以极大的减少代码量.递归的能力在于用有限的语句来定义对象的无限集合.
使用递归要注意的有两点:
1)递归就是在过程或函数里面调用自身;
2)在使用递归时,必须有一个明确的递归结束条件,称为递归出口.
递归分为两个阶段:
1)递推:把复杂的问题的求解推到比原问题简单一些的问题的求解;
2)回归:当获得最简单的情况后,逐步返回,依次得到复杂的解.
利用递归可以解决很多问题:如背包问题,汉诺塔问题,斐波那契数列为:1,1,2,3,5…
迭代:利用变量的原值推算出变量的一个新值.如果递归是自己调用自己的话,迭代就是A不停的调用B.
递归中一定有迭代,但是迭代中不一定有递归,大部分可以相互转换.能用迭代的不用递归,递归调用函数,浪费空间,并且递归太深容易造成堆栈的溢出.
def x(n):
n1=1
n2=1
n3=1
if n1 or n2:
return 1
while n-2>0:
n3=n2+n1
n1=n2
n2=n3
n=n-1
return n3
print(x(20))
枚举器,返回列表
enumerate(iterable,start=0)