函数

函数

1. 函数基础

  • 分类
    内置函数,自定义函数
  • 函数格式
def 函数名(形参1,形参2...)
    注释。。。
    函数体
    return 返回值
  • 调用规则
    先定义,后调用
  • 调用形式
语句形式:函数名()
表达式形式 
当另外一个函数的参数
  • 返回值 执行后需要有明确结果,就return
  • 函数参数
形参,实参

位置参数:  从左到右依次传值
关键字参数:   要在位置参数的右边,不能重复传值
可变长参数: *args接收位置参数,元组形式;  **kwargs 接收关键字参数 字典形式
默认参数:  在定义阶段给函数传值
在位置函数的右边,通常为不可变类型
命名关键字参数: * 后面定义的参数一定要以关键字实参的形式进行传值

2. 函数属性

  • 函数对象
可以被引用、当做参数、返回值可以是函数、可当做容器类型元素
  • 函数嵌套
函数作为方法在另外一个函数调用
def max(x,y):
    return x if x>y else y
def max3(f,g,t):
    res1=max(f,g)
    res2=max(res1,t)
    return res2
print(max3(4,6,7))
  • 名称空间与作用域
名称空间即存放变量名的空间,包含了变量名与变量值的绑定关系
加载顺序:内置名称空间,全局名称空间,局部名称空间
查找顺序:局部---》全局---》内置
注:全局无法查看局部,局部可以查看全局

作用域:
全局作用域
局部作用域
注:作用域关系在函数定义阶段已被固定,与函数调用位置无关
查找顺序(LEGB):本地作用域(Local)、嵌套作用域(Enclosing function locals)、全局作用域(Global)、内置作用域(builtins模块)

global:申明为全局  nonlocal申明为嵌套作用域
  • 闭包函数
内部函数包含对外部作用域(非全局)的引用
def outter(x):
    x=1
    def inner():
        print(x)
    return inner   #返回inner的内存地址

f=outter(18)    #outter()就是inner的内存地址
f()              #加()调用inner函数
#结果为 1

返回的不仅仅是一个函数对象,还有外层包裹的作用域,该返回的函数无论在何处调用,优先寻找包裹自己的作用域
  • 装饰器
无参:
def timmer(func):
    def wrapper(*args,**kwargs):
        res=func(*args,**kwargs)
        return res
    return wrapper
有参:
def auth(file='xx'):
    def timmer(func):
        def wrapper(*args,**kwargs):
            res=func(*args,**kwargs)
            return res
        return wrapper
    return timmer
    
wraps :不改变原有函数结构

3. 生成器与迭代器

  • 迭代器
定义:每一次重复即迭代,每一次迭代的结果,即下一层迭代的初始值
作用:让没有索引的数据类型进行取值
可迭代对象:包含__iter__方法的对象
迭代器对象: (1)可迭代对象执行__iter__()得到的结果即迭代器对象
(2)包含__iter__和__next__方法

for循环原理:
执行in 后对象的__iter__()方法得到迭代器对象,再执行next(对象),将得到的值赋给相关变量,循环取出 所有的值

优缺点:
不依赖于索引取值,惰性计算,节约内存;
无法获取对象长度,只往前无回退
  • 生成器
包含yield关键字,执行函数得到的结果即使生成器,生成对象,不执行函数代码,用next方法取值
def my_max(t):
    n,a,b=0,0,1
    while n<t:
        yield b #返回一个 iterable 对象,
        # print(b)
        a,b=b,a+b
        n+=1
res=my_max(6)
print(res) #<generator object my_max at 0x0041D3C0>
for i in res: # 
    print(i)
    
生成器即迭代器,有__iter__和__next__方法

yield:
将函数变成迭代器
可以返回多次值,保存函数状态
  • 面向过程 面向对象
复杂的问题简单化,进而流程化,可扩展性差

4. 函数应用

  • 三元表达式
条件成立时返回  if条件  条件不成立时返回
a,b=2,4
res=a if a>b else b
print(res)
  • 列表推导式
names = [x+'hb' for x in names]     #在列表的元素中加入hb
print(names)

l=[item**2 for item in range(1,11)]
print(l)

# names=['egon','alex_sb','wupeiqi','yuanhao']
# # 以sb结尾的名字过滤掉,然后保存剩下的名字长度
# names =[len(name)  for name in names  if not name.endswith('sb') ]
# print(names)
  • 生成器表达式
将列表推导式[]变成()即生成器表达式
一次值产生一个值,省内存

chicken=('鸡蛋%s' %i for i in range(5))
print(chicken)  #<generator object <genexpr> at 0x00691B40>得到生成器对象,通过next取值
  • 字典生成式
keys=['name','age','sex']
values=['egon',18,'male']
b={k,v for k,v in zip(keys,values)}
print(b)
  • 递归
在函数调用时,直接或者间接的调用到了本身
两个阶段:
回溯:由外到里
递推:由里到外,结束递归
指定递归次数:
sys.setrecursionlimit(limit)
  • 二分法
    取对象中间索引对应的值比较

4.1 匿名函数

lambda 形参 代码块 (实参)
res=(lambda x,y:x+y)(1,2)
print(res)
  • 偏函数
from functools  import partial
def func(num:int):
    return num**2
res=partial (func,10)
print(res())