python之函数作用域&装饰器
函数作用域
1.定义全局变量和局部变量并访问
count = 0 def f(): count = 10 print(count) print(count) f() #结果:控制台输出 # 0 #这个是 全局变量 count # 10 #这个是函数 f() 中的局部变量 count
2.对访问全局变量和局部变量的理解
#出错: count = 0 def f(): print(count) count = 10 f() #local variable 'count' referenced before assignment #赋值前引用的局部变量'count' ''' 原因(理解):程序在执行到 def f(): ,程序将该函数中的代码块先加载到内存中,在该函数被调用时,才开始执行代码 而此时,内存中已经存在局部变量 count ,所以在 print(count) 代码中可以找到 count 局部变量 而在执行 count = 10 代码之前, 执行print(count) ,所以会出现如下错误: #local variable 'count' referenced before assignment #赋值前引用的局部变量'count' '''
3.在函数中对全局变量的修改(global关键字的使用)
global_argu = 10 def f(): global global_argu global_argu =66666666 print("f() :" + str(global_argu)) f() #先执行 f() 函数,作用是:修改 全局变量 global_argu = 66666666 print(global_argu) #输出经过 f() 函数修改之后的全局变量global_argu = 66666666 # #结果 # # f() :66666666 # # 66666666
4.修改父函数的局部变量(nonlocal 关键字的使用)
def outer() : count = 10 def inner(): nonlocal count count = 20 print("inner() count :" + str(count))#inner() count :20 inner() print("outer() count:" + str(count)) #outer() count:20 # 结果:count 的值都为 20 outer() #结果 # inner() count :20 # outer() count:20 #结论:通过这种方式可以改变父函数中 count 变量的值
装饰器
装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则:
1 不修改被装饰对象的源代码
2 不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
无参装饰器
1.被修饰的函数无参
# import time # # def timer(func): # def wrapper(): # start_time = time.time() # func() # end_time = time.time() # print('耗时:',end_time-start_time) # return wrapper # # def foo(): # time.sleep(3) # print('foo function ...') # # foo = timer(foo) # foo() import time def timer(func): def wrapper(): start_time = time.time() func() end_time = time.time() print('耗时:',end_time-start_time) return wrapper @timer # foo = timer(foo) def foo(): time.sleep(3) print('foo function ...') foo() ''' 说明: @timer 相当于 foo = timer(foo) foo() '''
2.被修饰的函数有参数
import time def timer(func): def wrapper(*args,**kwargs): start_time = time.time() ret = func(*args,**kwargs) end_time = time.time() print('耗时:',end_time-start_time) return ret return wrapper @timer def max_f(a,b): time.sleep(2) if a>b: return a else: return b print(max_f(6,8)) print(max_f(9,2))
有参装饰器
# 有参装饰器 def auth(auth_type): def auth2(func): def wrapper(*args,**kwargs): if auth_type == 'file': name = input('name:').strip() password = input('password:').strip() # 读取文件获取内容 if name == 'puker' and password == '123': print('auth successfull') res = func(*args,**kwargs) return res else: print('fail auth') elif auth_type== 'mysql': print('从数据库中获取数据') return wrapper return auth2 @auth(auth_type='file') def index(): print('welcome to index page!') index()
被多个装饰器修饰
# @aaa # def func(): # pass # # # func=aaa(func) # @ccc # @bbb # @aaa # def func(): # pass # # func=ccc(bbb(aaa(func))) # # @ccc('c') # @bbb('b') # @aaa('a') # def func(): # pass # # func=ccc('c')(bbb('b')(aaa('a')(func)))
多个装饰器示例
import time current_login = {'name':None,'login':False} def timer(func): def wrapper(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs) end_time = time.time() print("耗时:",end_time-start_time) return res return wrapper def auth(auth_type): def auth2(func): def wrapper(*args,**kwargs): if current_login['name'] and current_login['login']: res = func(*args,**kwargs) return res if auth_type == 'file': name = input('name:').strip() password = input('password:').strip() if name == 'puker' and password == '123': print('successfull auth') res = func(*args,**kwargs) current_login['name'] = name current_login['login'] = True return res else: print('auth error') elif auth_type == 'mysql': print('从数据库中读取数据') return wrapper return auth2 @timer @auth(auth_type='file') def index(): print('welcome to index page!') @auth(auth_type='file') def home(): print('welcome to home page') index() home()
高阶函数
高阶函数定义:
1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名
3.满足上述条件任意一个,都可称之为高阶函数
一切不过是一个指针(变量),指向对应的内存区
闭包
只是对变量作用域的一种应用,在嵌套函数中,要拿到内嵌的函数,一定会通过外部的函数,而拿到内嵌的函数后,
该函数可以利用父函数

浙公网安备 33010602011771号