zoukankan      html  css  js  c++  java
  • 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()
    有参装饰器
  • 相关阅读:
    [Android学习笔记]Activity
    [Android学习笔记]Activity,View,Windows简介
    [Android]Eclipse的使用
    [Cocos2d-x]解决Android平台ndk-build时不自动删除外部库
    [Cocos2d-x]Android的android.mk文件通用版本
    [C++][STL]string记录
    nyoj-103-A+B Problem II
    nyoj-95-众数问题
    nyoj-187-快速查找素数
    nyoj-8-一种排序
  • 原文地址:https://www.cnblogs.com/Vae1242/p/6944285.html
Copyright © 2011-2022 走看看