首页 > 代码库 > Python学习之路7?装饰器

Python学习之路7?装饰器

一:命名空间与作用域

1.1命名空间

局部命名空间:

def foo():

  x=1

  def func():

    pass

全局命名空间:

import time

class ClassName:pass

def foo():pass

内键命名空间:

sum,max,min 等

python加载三个命名空间的顺序:

1.内键命名空间

2.全局命名空间:文件级别的或叫做模块级别的

3.局部命名空间:只有调用函数的时候才会加载,函数调用结束就被释放掉

1.2作用域

技术分享

全局作用域:

 1 同时x=1为全局变量
 2 x=1
 3 def func1():
 4     def func2():
 5         def func3():
 6             print(x)
 7         func3()
 8     func2()
 9 func1()
10 
11 输出结果
12 1

局部作用域:

 1 x=1
 2 def func1():
 3     def func2():
 4         def func3():
 5             x=100
 6             print(x)
 7         func3()
 8     func2()
 9 func1()
10 
11 
12 输出结果:
13 100

二:装饰器

2.1 什么是装饰器

器即函数

装饰即修饰,意指为其他函数添加新功能

装饰器定义:本质就是函数,功能是为其他函数添加新功能

2.2 实现装饰器知识储备

装饰器=高阶函数+函数嵌套+闭包

2.3 装饰器需要遵循的原则

1.不修改被装饰函数的源代码(开放封闭原则)

2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式

3装饰器是在遵守1和2的前提下,为被装饰的对象添加新功能

2.4 装饰器无参基本框架

1 #这就是一个实现一个装饰器最基本的架子
2 def timer(func):
3     def wrapper():
4         func()
5     return wrapper

2.5 装饰器有参基本框架

1 def timer(func):
2     def wrapper(*args,**kwargs):
3          func(*args,**kwargs)
4     return wrapper

2.6 无参装饰器

 1 import time
 2 def timer(func): #func=最原始的index
 3     def warpper():
 4         start_time=time.time()
 5         func()
 6         end_time=time.time()
 7         print(run time is %s % (end_time - start_time))
 8     return warpper
 9 
10 #无参装饰器
11 @timer #index=timer(index) 此时的index就是warpper
12 def index():
13     time.sleep(1)
14     print("welcome to index")
15 
16 index()#就是在调用warpper()
17 
18 原来的index的函数只会输出welcome to index
19 加上装饰器后;
20 输出内容为:
21 welcome to index
22 run time is 1.0060575008392334

2.7 有参数装饰器

 1 import time
 2 def timer(func): #func=最原始的index
 3     def warpper(user):
 4         start_time=time.time()
 5         func(user)
 6         end_time=time.time()
 7         print(run time is %s % (end_time - start_time))
 8     return warpper
 9 
10 @timer #index=timer(index) 此时的index就是warpper
11 def home(user):
12     time.sleep(1)
13     print("home %s"% user)
14 
15 home(tom)#就是在调用warpper()
16 
17 输出结果:
18 home tom
19 run time is 1.0000574588775635

2.8 如果传入的参数是关键字类型

 1 import time
 2 def timer(func): #func=最原始的index
 3     def warpper(*args,**kwargs):
 4         start_time=time.time()
 5         func(*args,**kwargs)
 6         end_time=time.time()
 7         print(run time is %s % (end_time - start_time))
 8     return warpper
 9 
10 @timer #index=timer(index) 此时的index就是warpper
11 def home(user):
12     time.sleep(1)
13     print("home %s"% user)
14 
15 home(tom)#就是在调用warpper()
16 home(user="yyp")
17 #输出结果:
18 home tom
19 run time is 1.0000574588775635
20 home yyp
21 run time is 1.0000569820404053

2.9 如果原函数有返回值

 1 import time
 2 def timer(func): #func=最原始的index
 3     def warpper(*args,**kwargs):
 4         start_time=time.time()
 5         res=func(*args,**kwargs)
 6         end_time=time.time()
 7         print(run time is %s % (end_time - start_time))
 8         return res
 9     return warpper
10 
11 @timer #index=timer(index) 此时的index就是warpper
12 def home(user):
13     time.sleep(1)
14     return user +  is student
15 
16 res=home(tom)#就是在调用warpper()
17 print(res)
18 #输出结果:
19 run time is 1.0000574588775635
20 tom is student

三:闭包

闭包:本质就是一个内部函数

特点:这个内部函数必须包含对外部函数作用域(非全局作用)名字的引用

示例:

 1 def f1():
 2     x=1
 3     y=2
 4     def f2():
 5         print(x)
 6         print(y)
 7     return f2
 8 
 9 func=f1()
10 #func()
11 print(func.__closure__[0].cell_contents)#查看闭包函数的方法
12 print(func.__closure__[1].cell_contents)
13 
14 #f2为闭包函数
15 
16 输出结果:
17 1
18 2

惰性计算:啥时候用啥时候调用

 1 from urllib.request import urlopen
 2 
 3 def page(url): 
 4     def get():
 5         return urlopen(url).read()
 6     return get
 7 
 8 baidu=page(‘http://www.baidu.com‘)
 9 python=page(‘http://www.python.org‘)
10 
11 print(baidu)
12 print(python)
13 
14 输出结果:
15 <function page.<locals>.get at 0x0000000002DE6BF8>
16 <function page.<locals>.get at 0x0000000002DE6C80>
17 
18 函数没有执行,已经传了一个参数

四:装饰器应用示例

技术分享
 1 user_list=[
 2     {name:tom,passwd:123},
 3     {name:yyp,passwd:123},
 4     {name:sy,passwd:123},
 5     {name:ly,passwd:123},
 6 ]
 7 
 8 current_user={username:None,login:False}
 9 
10 def auth_deco(func):
11     def wrapper(*args,**kwargs):
12         if current_user[username] and current_user[login]:
13             res=func(*args,**kwargs)
14             return res
15         username=input(用户名: ).strip()
16         passwd=input(密码: ).strip()
17 
18         for index,user_dic in enumerate(user_list):
19             if username == user_dic[name] and passwd == user_dic[passwd]:
20                 current_user[username]=username
21 
22                 current_user[login]=True
23                 res=func(*args,**kwargs)
24                 return res
25                 break
26         else:
27             print(用户名或者密码错误,重新登录)
28 
29     return wrapper
30 
31 @auth_deco
32 def index():
33     print(欢迎来到主页面)
34 
35 @auth_deco
36 def home():
37     print(这里是你家)
38 
39 def shopping_car():
40     print(查看购物车啊亲)
41 
42 def order():
43     print(查看订单啊亲)
44 
45 print(user_list)
46 # index()
47 print(user_list)
48 home()
无参装饰器
技术分享
 1 user_list=[
 2     {name:tom,passwd:123},
 3     {name:yyp,passwd:123},
 4     {name:sy,passwd:123},
 5     {name:ly,passwd:123},
 6 ]
 7 
 8 current_user={username:None,login:False}
 9 def auth(auth_type=file):
10     def auth_deco(func):
11         def wrapper(*args,**kwargs):
12             if auth_type == file:
13                 if current_user[username] and current_user[login]:
14                     res=func(*args,**kwargs)
15                     return res
16                 username=input(用户名: ).strip()
17                 passwd=input(密码: ).strip()
18 
19                 for index,user_dic in enumerate(user_list):
20                     if username == user_dic[name] and passwd == user_dic[passwd]:
21                         current_user[username]=username
22                         current_user[login]=True
23                         res=func(*args,**kwargs)
24                         return res
25                         break
26                 else:
27                     print(用户名或者密码错误,重新登录)
28             elif auth_type == ldap:
29                 print(巴拉巴拉小魔仙)
30                 res=func(*args,**kwargs)
31                 return res
32         return wrapper
33     return auth_deco
34 
35 
36 #auth(auth_type=file)就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type=file)
37 #就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type=file参数
38 @auth(auth_type=ldap)
39 def index():
40     print(欢迎来到主页面)
41 
42 @auth(auth_type=ldap)
43 def home():
44     print(这里是你家)
45 
46 def shopping_car():
47     print(查看购物车啊亲)
48 
49 def order():
50     print(查看订单啊亲)
51 
52 # print(user_list)
53 index()
54 # print(user_list)
55 home()
有参装饰器

 

Python学习之路7?装饰器