函数作用域

L -> E -> G -> B 查找规则

  1. 局部作用域 L
  2. 闭包函数外到函数中 E
  3. 全局作用域 G
  4. 内建作用域 B
  5. global 关键字可以修改全局变量 nonlocal 关键字 声明函数内使用同一个变量
  6. 案例
    a = 10 def test(): a = a + 1 print(a) test() ​ # 报错 因为函数内的a使用前没有被定义
     
递归函数

概念

自己调用自己的函数称为递归函数。一般是不知道要循环多少次的函数例如阶乘、 查找文件夹内所有文件的大小。与while的区别是递归函数有递推的过程每次执行都会有返回值传给调用处

实例

# 递归函数分解
def fun(a):
if a == 1:
return 1
return a + fun1(a - 1)


def fun1(a):
if a == 1:
return 1
return a + fun2(a - 1)


def fun2(a):
if a == 1:
return 1
return a + fun3(a - 1)


def fun3(a):
if a == 1:
return 1
return a + fun4(a - 1)


def fun4(a):
if a == 1:
return 1


print(fun(4))

# 递归函数
def res(b):
if b == 1:
return 1
return b + res(b - 1)


print(res(4))


实例2

# 阶乘
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
fact(10) # 求1*2*3..10


# 计算过程
===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 0)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120


 

函数闭包

与函数嵌套类似,函数闭包返回的是函数

def fun1():
# name = 'abc'
def fun2():
# name = 'xx'
print('我是fun2函数', name)
return fun2

v = func1()
v()


上面的定义的函数的返回值是一个包含在func1函数中的一个函数,v指向func2函数的内存地址,加()执行func2

装饰器

概念

在不改变原函数代码和调用情况的前提下将原函数闭包在另外一个函数内,并在原函数执行前后扩展原函数的功能 常用的场景 比如插入日志 事物处理 缓存 权限校验等

格式:在原函数的上面加 @装饰函数名

实例

import functools  


def outer(origin):
@functools.wraps(func) #
def inner(*args, **kwargs):
# 执行前
res = origin(*args, **kwargs) # 调用原来的func函数
# 执行后
return res
return inner


@outer
def func():
pass

func()


实例2

日志案例

import logging

def user_logging(func):
def inner():
func()
logging.warning('{} is running'.format(func.__name__))
return inner

@user_logging
def test():
print('im test')

@user_logging
def test2():
print('im test2')


func.__name__获取的是原函数的名字 ,因此在装饰器内要加@functools.wraps(func)

防止引入错误

高阶函数

1. map

  • map(函数,可迭代对象)
  • 返回map对象 可迭代
  • 功能:将函数作用在可迭代对象的每个元素上
  • 实例
    List = ['1', '2', '3', '4', '5'] # 将列表中的元素转为整形 传入的lambda表达式 res = map(lambda x:int(x), List) print(list(res)) print(res) # [1, 2, 3, 4, 5] # <map object at 0x0000021B4C0E6808> ​ # 传入自定义函数 def changInt(x): print(x, type(x)) return int(x) ​ res = list(map(changInt, List)) print(res) ​ # 传入内置函数 print(list(map(int, List))) print(list(map(bool, List))) print(list(map(float, List)))

2.reduce

  • reduce(函数,可迭代对象)
  • 将可迭代对象中的每个元素放在函数中累加,必须传2个参数
  • 实例
     
    from functools import reduce ​ List = list(range(10)) ​ ​ # print(List) ​ def mySum(x, y): print(x, y) return x + y ​ ​ res = reduce(mySum, List) print(res) ​ ''' 0 1 1 2 3 3 6 4 10 5 15 6 21 7 28 8 36 9 45 '''
     
    # 将字符串转换成整数12345 string = '12345' res = reduce(lambda x, y: x * 10 + y, list(map(int, string))) print(res)

3.filter

  • filter(函数,可迭代对象)
  • 返回filter对象
  • 过滤集合 将函数作用在每个元素上
  • 实例
    List = list(range(1, 11)) # 获取列表中所有的偶数 # print(List) for i in List: if i % 2 == 0: print(i) ​ def fun(i): if not i % 2: return True return False ​ res = filter(fun, List) print(list(res)) ​ ​ ''' 2 4 6 8 10 [2, 4, 6, 8, 10] '''
  • 去除空字符串
    List2 = ['1', '2 ', ' 3', ' ', '', ""] def demo(i): return i and i.strip() ​ res = filter(demo, List2) print(list(res))

4.sorted

  • sorted(函数,key=‘ ’) key 系统关键字
  • 排序
  • 实例
    List = [1, 2, -5, -4, 3] res = sorted(List) # 反转 res = sorted(List, reverse=True) # 反转 print(res) ​ List2 = ['a', 'aasc', 'ab', 'vabcd'] print(sorted(List2)) print(sorted(List2, key=len)) # 根据长度排序 ​ ''' [-5, -4, 1, 2, 3] ['a', 'aasc', 'ab', 'vabcd'] ['a', 'ab', 'aasc', 'vabcd'] '''