#11.27-day9-名称空间与作用域、闭包函数、装饰器
一、名称空间和作用域
1、什么是间名称 namespace
定义:名称空间就是存放名字的地方
名称空间分为三类
内置名称空间:存放内置的名字,该名称空间随着解释器启动就产生,解释器关闭则销毁
len
print
input
全局名称空间:存放的是顶级的名字,运行文件的顶级代码前产生,文件运行完毕则销毁
局部名称空间:在函数内定义的名字,调用函数则产生一个函数局部名称空间,该函数调用结束则立即销毁
查找名字的优先级
局部名称空间--------》全局名称空间----------》内置名称空间
示例1
x=10 #全局名称空间
def f1(): #f1本身也是全局名称空间
y=2 #局部名称空间
if 1>0:
z=3 #全局名称空间
if 3>1:
M=111 #全局名称空间
示例2
len=1111
def f1():
len=2222
print(len)
f1() #结果是----2222
print("------",len) #结果是11111
重要概念
名称空间的嵌套关系是在函数定义阶段,即检测语法时确定的,与函数调用阶段是无关,与函数定义位置有关
示例1
x=1000
def f1():
print(x) #报错,不应在调用x变量前,先使用x
x=2222
f1()
示例2
x=1000
def f1():
print(x)
def f2():
x=200
f1()
f2() #结果是1000
2、全局作用域
定义:内置名称空间 + 全局名称空间
特点:全局存活,全局有效
3、局部作用域
定义:局部名称空间
特点:临时存活,局部有效
#global
x=1000
def f1():
global x #改全局x
x=2000
f1()
print(x) #结果为2000
#nonlocal
x=1000
def f1():
x=222
def f2():
nonlocal x #改局部作用域
x=333
f2()
print(x) #结果为333
f1()
二、闭包函数
1.闭函数
定义·:该函数是定义在一个函数内部的函数
2.包函数
定义:闭函数引用了一个来自于外层函数的变量
示例1:
def outter():
x=111
def warpper():
print(x)
return warpper #!!!千万别加()
f=outter()
print() #打印函数warpper的地址
x=222
f() #结果为111
def f2():
x=3333
f()
f2() #结果仍未111
3、为函数传参的两种方式:
方式一:
def warrper(x):
print(x)
warrper(10)
warrper(20)
方式二:闭包
def outter(x):
def warpper():
print(x)
return warpper
f=outter(20)
f() #打印20
三、装饰器
1.什么是装饰器?
器-------》工具
装饰--------》添加新功能
装饰器就是定义个函数,用该函数去为其他函数添加新功能
2.为何用装饰器
开放封闭原则:针对上线的功能对拓展是开放的,但是对修改源代码以及调用方式是封闭的
装饰器就是在遵循开放封闭原则的前提下为被装饰对象添加新功能
1、不修改被装饰对象的源代码
1、不修改被装饰对象的调用方式
3.如何用装饰器
需求:为index加上新功能-》统计其运行时间
import time
def index():
time sleep(1)
print('from index')
index
方案1
#功能达到了,但是改变了源代码
import time
def index():
start = time.time()
time.sleep(1)
print('form index')
stop = time.time()
print('run time %s' % (stop - start))
index()
方案2
#没有改变函数源代码,但是如果此函数被多此调用,就会产生多行重复代码
import time
def index():
time.sleep(1)
print('from index')
start = time.time()
index()
stop = time.time()
print('run time %s' % (stop - start))
方案3
#改变了函数的调用方式,而且只能被一个函数使用
import time
def index():
time.sleep(1)
print('from index')
def warpper():
start = time.time()
index()
stop = time.time()
print('run time %s' % (stop - start))
warpper()
方案3.1
#函数的调用方式被改变,但是此装饰器被写活了
import time
def index():
time.sleep(1)
print('from index')
def warpper(f):
start = time.time()
f()
stop = time.time()
print('run time %s' % (stop - start))
warpper(index)
方案3.2
#闭包函数
import time
def index():
time.sleep(1)
print('from index')
def outter(f): #f值为index的内存地址
def warpper():
start = time.time()
f() #函数index的内存你地址()
stop = time.time()
print('run time %s' % (stop - start))
return warpper
f = outter(index) #函数outter(index的内存地址)
index = f
index()
改进方案1
#函数有参
import time
def home(name):
time.sleep(2)
print('home page,welecome %s' % name)
def outter(f): #f是home的内存地址
def warpper(name):
start = time.time()
f(name) #
stop = time.time()
print('run time %s' % (stop - start))
return warpper
home = outter(home)
home("egon")
改进2
#有参和无参都可输入
import time
def index():
time.sleep(1)
print('from index')
def home(name):
time.sleep(2)
print('home page,welecome %s' % name)
def outter(f): #f是home的内存地址
def warpper(*args,**kwargs):
start = time.time()
f(*args,**args)
stop = time.time()
print('run time %s' % (stop - start))
return warpper
home = outter(home)
home("egon")
改进3
·#函数的返回值也可以正常返回
import time
def index():
time.sleep(1)
print('from index')
def home(name):
time.sleep(2)
print('home page,welecome %s' % name)
return 123
def outter(f):
def warpper(*args,**kwargs):
start = time.time()
res=f(*args,**kwargs)
stop = time.time()
print('run time %s' % (stop - start))
return res
return warpper
home = outter(home)
print(home("egon"))