zoukankan      html  css  js  c++  java
  • 第九篇装饰器基本原理

    #装饰器:本质就是函数,功能就是为其他函数添加附加功能
    #原则
    1.不修改被修饰函数的源代码
    2.不修改被修饰函数的调用方式
    装饰器=高阶函数+函数嵌套+闭包
    #高阶函数
    定义:1.函数接收的参数是一个函数名
          2.函数的返回值是一个函数名 (满足其一即可)

    上节复习回顾补充

     装饰器1

     

    高阶函数的使用

     函数的嵌套

    加上返回值

    加上参数

    验证功能实现

    user_list=[
    {'name':'alex','passwd':'123'},
    {'name':'linhaifeng','passwd':'123'},
    {'name':'wupeiqi','passwd':'123'},
    {'name':'yuanhao','passwd':'123'},
    ]
    current_dic={'username':None,'login':False}


    def auth_func(func):
    def wrapper(*args,**kwargs):
    if current_dic['username'] and current_dic['login']:
    res = func(*args, **kwargs)
    return res
    username=input('用户名:').strip()
    passwd=input('密码:').strip()
    for user_dic in user_list:
    if username == user_dic['name'] and passwd == user_dic['passwd']:
    current_dic['username']=username
    current_dic['login']=True
    res = func(*args, **kwargs)
    return res
    else:
    print('用户名或者密码错误')

    return wrapper

    @auth_func
    def index():
    print('欢迎来到京东主页')

    @auth_func
    def home(name):
    print('欢迎回家%s' %name)

    @auth_func
    def shopping_car(name):
    print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))

    print('before-->',current_dic)
    index()
    print('after--->',current_dic)
    home('产品经理')
    # shopping_car('产品经理')

    
    
    
    
    
    
    
    
    
    
    复制代码
    #简单的装饰器
    import time
    def timer(func):
        def wrapper():                       #*args接受元组系列 **kwargs接收字典系列
            start_time=time.time()
            res=func()                   #函数嵌套
            stop_time=time.time()
            print('All time %d' %(stop_time-start_time))
            return res
        return wrapper
    
    
    @timer  #相当于text=timer(text)
    def text():
        time.sleep(3)
        print("end.....")
    text()    
        
    复制代码
    复制代码
    def list_diedai(fun):
        def wrapper(*args,**kwargs):  #*args=(num)  **kwargs={'num':4}
            res=fun(*args,**kwargs)   #*args将接收的参数转化成列表
            return res.__iter__         #**kwargs将接受的参数转化成字典
        return wrapper          #返回地址
    
    @list_diedai
    def list1(num):
        return [x for x in range(int(num))]
    p1=list1(4)
    print(p1)       #<method-wrapper '__iter__' of list object at 0x009D45A8>
    print(p1())       #<list_iterator object at 0x00A93250>
    p2=p1()
    print(p1().__next__())     #  0
    print(next(p1()))           #  0
    print(p2.__next__())        #  0
    print(next(p2))             #   1
    print(next(p2))             #   2
    print(p2.__next__())          #  3
    复制代码

     #类的装饰器(进阶) 
    #万能参数添加器

    复制代码
    def Type(**kwargs):
        print(kwargs)    #{'x': 7, 'j': 9}
        def deco(obj):
            print(obj)   #<class '__main__.Int'>
            for key,val in kwargs.items():
                setattr(obj,key,val)
            return obj
        print(deco)  #<function Type.<locals>.deco at 0x01760AE0>
        return deco
    @Type(x=7,j=9)
    class Int:
        pass
    复制代码

    #装饰器应用进阶

    复制代码
    class Type:
        def __init__(self,x,excepet_type):    #巧妙灵活
            self.x=x
            self.excepet_type=excepet_type
    
        def __get__(self, instance, owner):
            # print(instance,owner)
            return instance.__dict__[self.x]
    
        def __set__(self, instance, value):
            # print(instance,value)
            if type(value)!=self.excepet_type:
                print('%s 传入的不是 %s ,错误!!!' %(self.x,self.excepet_type))
                return
            instance.__dict__[self.x]=value
    
        def __delete__(self, instance):
            instance.__dict__.pop(self.x)
    
    def Type1(**kwargs):
        def warpper(obj):
            for key,val in kwargs.items():
                setattr(obj,key,Type(key,val))
            return obj
        return warpper
    
    @Type1(name=str,age=int) #先运行Type1(name=str,age=int)函数
    #得到warpper的返回值,在运行 People=warpper(People)
    class People:
        # name=Type('name',str) #描述符代理
        # age=Type('age',int)
        def __init__(self,name,age,salary):
            self.name=name
            self.age=age
            self.salary=salary
    p=People('lujiacheng','3',5000) #age 传入的不是 <class 'int'> ,错误!!!
    print(p.__dict__)  #{'name': 'lujiacheng', 'salary': 5000}
    
    p.name=98  #name 传入的不是 <class 'str'> ,错误!!!
    print(p.__dict__) #{'name': 'lujiacheng', 'salary': 5000}
    
    p.name='98'
    print(p.__dict__)  #{name': '98', 'salary': 5000}
    del p.name
    print(p.__dict__)  #{'salary': 5000}
    复制代码

    #类装饰器

    复制代码
    class lazyproperty:
        def __init__(self,fun):
            self.func=fun
    
        def __get__(self, instance, owner):
            if instance is None:
                return self
            return self.func(instance)
    
    class Room:
        def __init__(self,name,width,length):
            self.name=name
            self.width=width
            self.length=length
    
        # @property #  area=property(area)
        @lazyproperty
        def area(self):
            return self.width*self.length
    
    r=Room('dd',45,56)
    print(r.area)  #  2520
    print(Room.area)  #<__main__.lazyproperty object at 0x0072E8B0>
    复制代码
  • 相关阅读:
    java IO
    免费的编程中文书籍索引-转
    js两种定义函数、继承方式及区别
    为什么这样写js:(function ($) { })(jQuery);
    Cannot open connection 解决办法
    dos下mysql登陆
    spring-AOP-1
    el表达式
    设计模式——"simple Factory"
    软件生产性控制
  • 原文地址:https://www.cnblogs.com/ZT152156/p/10440381.html
Copyright © 2011-2022 走看看