Python 作用域 高阶函数 装饰器

Python 作用域 高阶函数 装饰器

1.作用域
1.python的作用域由大到小一共四个级别,分别如下:
1.) 内键(Built-in)B
全局(Global)G
闭包内(Encloseing)E
局部作用域 (Local) L
2.) 只有class import def lambda 关键字才能引入作用域。
3.)遵循开闭原则 : 上不能访问修改,下可以访问不能修改上(向下开放,向上闭合)
4.) 内键作用域中的变量列表使用__builtins__ 变量
print("builtins ")
作用域:python环境,调用的库
5.)全局作用域中的变量列表查看 globals()
globals()
我们可以在当前文档的任意位置使用 global 关键字显示声明一个全局变量
Python 作用域 高阶函数 装饰器_第1张图片
Python 作用域 高阶函数 装饰器_第2张图片

使用 locals() 查看当前作用域
globals() == locals()
作用域:
6.) 闭包内(Encloseing)作用域
Python 作用域 高阶函数 装饰器_第3张图片
类似于上面例子当中的abc变量位置(在闭包函数外,函数之内)的变量作用域就是闭包内
闭包就是函数内部函数的嵌套
闭包:在闭包函数外,函数之内

nonlocal关键字
Python 作用域 高阶函数 装饰器_第4张图片
Python 作用域 高阶函数 装饰器_第5张图片

以上示例演示了 nonlocal关键字声明函数内的变量为非局部变量。该关键字仅能引用上级的闭包内作用域中

2.高阶函数
1.函数的对象属性
函数本身也是对象,可以作为参数传入函数。
回调函数
Python 作用域 高阶函数 装饰器_第6张图片

2.递归函数
1.)表现及定义:在函数的内部对函数进行调用,我们称之为递归。
注意设定递归的终止条件。
python中的递归层级最大为1000(参考值,与环境有关993)
2.)九成以上递归问题可以被转化为迭代问题处理。
递归的好处是我们只需要知道结果的前一个状态就可以进行计算

关于使用递归解决阶乘的示例
def f(n):
if n == 1:
return 1
else:
return f(n-1)*n
print(f(5))
Python 作用域 高阶函数 装饰器_第7张图片
普通递归在计算次数上面比迭代至少多了一倍,因为递归首先要对计算结果进行推断。

尾递归问题优化:(对于下次计算将本次的已知结果进行带入使得最后一次递归结果直接获得结果)
def f(n,m = 1):
if n == 1:
return 1m
else:
return f(n-1,m
n)
print(f(5,1))
Python 作用域 高阶函数 装饰器_第8张图片

  1. 匿名函数
    python中的匿名函数仅仅是一个lambda表达式
    格式 lambda arg1[,arg2… …]:表达式
    返回表达式的结果
    例:
    a = lambda x,y: x+y
    print(a(1,2))
    #上面的函数等价于
    def a(x,y):
    return x+y
    print(a(1,2))
    在这里插入图片描述

4.偏函数
偏函数本质上就是一个函数的分身

def f1(a,b,c,d,e):
print(a,b,c,d,e)
#导入函数工具包中的偏函数功能
from functools import partial
#构造一个f1的偏函数 f2
f2 = partial(f1,c=“妹”,d=“吃”)
f2(a=“南”,b=“妹”,e=“牛”)
#构造一个f1的偏函数 f3
f3 = partial(f1,a=1)
f3(b=“b”,c=“c”,d=“d”,e=“g”)

3.装饰器(装饰函数)
1.定义及应用
装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。
饰器的作用就是为已经存在的对象添加额外的功能。
当我们定义好一个装饰函数时,需要使用@语法糖将该装饰器用来装饰被装饰函数。其本身是将被装饰函数作为参数传入装饰器中并执行,得到其返回值重新赋值给被装饰函数的表计量。
主要形式有两大类型(不带参数的装饰器、带参数的装饰器)
例:
import time #时间模块
def a():
print(“Hello 西红柿”)
def timer(fun):
start = time.time()
fun()
end = time.time()
print(end-start)
timer(a)
在这里插入图片描述

2.不带任何参数的装饰器
import time
def show_time(fun):
def inner(*args,**kwargs):
start = time.time()
fun(*args,**kwargs)
end = time.time()
print(end-start)
return inner
@show_time
def fun(name,age):
print(name,age)
fun(“xx”,250)
在这里插入图片描述

Python 作用域 高阶函数 装饰器_第9张图片
不带参数的装饰器的执行流程:
遇到@语句将@引导的装饰函数直接执行(执行时的参数为这个语句紧跟的函数对象本身)再将装饰函数的执行结果重新赋值给被装饰的函数的名字。
我们对当前函数的执行,本质上是执行的是装饰函数的返回对象。
不带参数的装饰器的参考写法
无参装饰器逻辑
Python 作用域 高阶函数 装饰器_第10张图片


def 装饰函数(fun):
def inner(*args,**kwargs)
[装饰逻辑]
result = fun(*args,**kwargs)
[装饰逻辑]
return result
return inner
@ 函数名 对其紧跟的函数进行装饰


时间装饰器
import time
def show_time(fun):
def inner(*args,**kwargs):
start = time.time()
result = fun(*args,**kwargs)
end = time.time()
print(end-start)
return result
return inner
@show_time


分隔符装饰器****
import math
def xing(fun):
def inner(args,kwargs):
result = fun(args,kwargs)
print("
")
return result
print("
*")
return inner
@xing

3.含参数的装饰器
Python 作用域 高阶函数 装饰器_第11张图片
Python 作用域 高阶函数 装饰器_第12张图片

def show_info(name,age):
def outer(fun):
def inner(*args,**kwargs):
print(“装饰执行”,name)
result = fun(*args,**kwargs)
print(“装饰结束”,age)
return result
return inner
return outer

@show_info(“abc”,111)
def fun1(num):
print(num)
@show_info(“xyz”,153)
def fun2(num):
print((num+23)//32)

print(fun1(1233333))
print("***************************")
print(fun2(999999))


用时间装饰器比较 ** pow 阶乘法时间快慢
import time
import math
def show_info(NN,MM):
def outer(fun):
def inner(*args,**kwargs):
start = time.time()
result = fun(*args,**kwargs)
end = time.time()
print(end-start,NN,MM)
return result
return inner
return outer

@show_info("此处为所用时间",“呵呵呵”)
def fun1(num1,num2):
print(num1
num2)
@show_info(“此处为pow函数所用时间”,“呵呵呵”)
def fun2(num1,num2):
print(pow(num1,num2))

print(fun1(66,66))
print("***************************")
print(fun2(66,66))
Python 作用域 高阶函数 装饰器_第13张图片


4.装饰器特性
1.)装饰器修改了被装饰的函数
2.)在模块(文件)中装饰器是在被加载时执行的
3.)多个装饰器同时装饰一个被装饰函数时,按照被装饰顺序进行装饰
Python 作用域 高阶函数 装饰器_第14张图片
先用a装饰,再用b装饰, 最后用c装饰

你可能感兴趣的:(基础知识)