zoukankan      html  css  js  c++  java
  • 24、Python之有参装饰器

    一、前置知识

    1.1 无参装饰器模板

    def outter(func):
        def wrapper(*args,**kwargs):
            # 1、调用原函数
            # 2、给原函数增加新的功能
        	res=func(*args,**kwargs)
        	# 3、给原函数增加新的功能
        	return res
        return wrapper
    
    @outter # index=outter(index)
    def index(x,y):
        """这个是主要功能"""
        print(x,y)
        
    print(index) # <function outter.<locals>.wrapper at 0x0000027FF77B20D0>
    print(index.__name__) # wrapper,实际上还是wrapper函数
    print(help(index)) # wrapper的文档注释如下:
    '''
    Help on function wrapper in module __main__:
    
    wrapper(*args, **kwargs)
        这个是主要功能
    
    None
    '''
    # 经装饰之后的函数,还是没有完全伪装的跟原函数一样,需要继续优化
    

    1.2 装饰器wraps

    #偷梁换柱,即将原函数名指向的内存地址偷梁换柱成wrapper函数,所以应该将wrapper做的跟原函数一样才行
    
    from functools import wraps  # 引入functools模块下的装饰器wraps
    
    def outter(func):
        @wraps(func)  # functools模块下提供的装饰器wraps,可以实现保留原函数属性的操作
        def wrapper(*args,**kwargs):
            # 1、调用原函数
            # 2、给原函数增加新的功能
        	res=func(*args,**kwargs)
        	# 3、给原函数增加新的功能
        	return res
        return wrapper
    
    

    二、有参装饰器

    2.1 有参装饰器的实现

    若在无参装饰器的基础上,再实现一个用来为被装饰对象添加认证功能的装饰器,需要在deco外部再包一层函数auth,用来专门接受额外的参数,这样便保证了在auth函数内无论多少层都可以引用到。

    def auth(db_type):
        def deco(func):
            def wrapper(*args, **kwargs):
                name = input('your name>>>: ').strip()
                pwd = input('your password>>>: ').strip()
    
                if db_type == 'file':
                    print('基于文件的验证')
                    if name == 'egon' and pwd == '123':
                        res = func(*args, **kwargs)  # index(1,2)
                        return res
                    else:
                        print('user or password error')
                elif db_type == 'mysql':
                    print('基于mysql的验证')
                elif db_type == 'ldap':
                    print('基于ldap的验证')
                else:
                    print('不支持该db_type')
            return wrapper
        return deco
    
    
    @auth(db_type='file')  # @deco # index=deco(index) # index=wrapper
    def index(x, y):
        print('index->>%s:%s' % (x, y))
    
    @auth(db_type='mysql')  # @deco # home=deco(home) # home=wrapper
    def home(name):
        print('home->>%s' % name)
    
    
    @auth(db_type='ldap')  # 账号密码的来源是ldap
    def transfer():
        print('transfer')
    
    index(1, 2)
    home('egon')
    transfer()
    

    2.2 有参装饰器模板

    def 有参装饰器(x,y,z):
        def outter(func):
            def wrapper(*args, **kwargs):
            	# 1、为其增加新功能
                res = func(*args, **kwargs)
                return res
                # 2、调用原函数后为其增加其他新功能
            return wrapper
        return outter
    
    @有参装饰器(1,y=2,z=3)
    def 被装饰对象():
        pass
    
  • 相关阅读:
    How to create jar for Android Library Project
    Very large tabs in eclipse panes on Ubuntu
    64bit Ubuntu, Android AAPT, R.java
    Linux(Ubuntu)下如何安装JDK
    Configure xterm Fonts and Colors for Your Eyeball
    建立、配置和使用Activity——启动其他Activity并返回结果
    建立、配置和使用Activity——使用Bundle在Activity之间交换数据
    建立、配置和使用Activity——启动、关闭Activity
    建立、配置和使用Activity——Activity
    异步任务(AsyncTask)
  • 原文地址:https://www.cnblogs.com/zuiyouyingde/p/12559496.html
Copyright © 2011-2022 走看看