zoukankan      html  css  js  c++  java
  • python 装饰器

    1.闭包函数

    首先了解闭包:在函数中再嵌套一个函数,并且引用外部函数的变量,这就是一个闭包了。

    实例如下:

    def outer(x):
        def inner(y):
            return x+y
        return inner
    
    print(outer(6)(5))

    输出如下:

    11

    函数解释:定义一个函数outer,参数为:x,在outer函数内又定义了inner函数,引用外部的x参数,这就是闭包函数。在输出时,outer(6)(5),第一个括号传进去的值返回inner函数,其实就是返回6 + y,所以再传第二个参数进去,就可以得到返回值,6 + 5。

    2.装饰器

      装饰器就是一个闭包函数,是闭包的一种应用。python装饰器是用于拓展原功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的喊出就是在不用更改原函数的代码前提下给函数增加新的功能。装饰器书写“@func”

    def  debug(func):
        def wrapper():
            print("[DEBUG]:enter{}()".format(func.__name__))
            return func()
        return wrapper
    
    
    @debug
    def hello():
        print("hello")
    
    hello()
    输出:
    [DEBUG]:enterhello()
    hello

    3.带参数的装饰器

    def logging(level):
        def outwrapper(func):
            def wrapper(*args, **kwargs):
                print("[{0}]:enter {1}()".format(level, func.__name__))
                return func(*args, **kwargs)
            return wrapper
        return outwrapper
    
    
    @logging(level="INFO")
    def hello(a,b,c):
        print(a, b,c)
    
    hello("hello", "good", "morning")
    ------------------------------------
    [INFO]:enter hello()
    hello good morning

    如上,装饰器中可以传入参数,先形成一个完整的装饰器,然后再来装饰函数,当然函数如果需要传入参数也是可以的,用不定长参数符号就可以接收,例子中传入了三个参数。

    4.类装饰器

    类装饰其用法与函数装饰器并没有太大区别,实质时使用了类方法中的call魔法来实现类的直接调用

    class logging():
        def  __init__(self,func):
            self.func = func
        
        def __call__(self, *args, **kwargs):
            print("[DEBUG]: enter {}()".format(self.func.__name__))
            return self.func(*args, **kwargs)
    
    
    @logging
    def hello(a, b,c):
        print(a,b,c)
    
    hello("hello", "good", "morning")
    --------------------------------------------
    [DEBUG]: enter hello()
    hello good morning

    带参数的类装饰器:

    class logging():
        def __init__(self, level):
            self.level = level
        
        def __call__(self, func):
            def wrapper(*args, **kwargs):
                print("[{0}]: enter {1}()".format(self.level, func.__name__))
                return func(*args, **kwargs)
            
            return wrapper
    
    
    @logging(level="TEST")
    def hello(a, b, c):
        print(a, b, c)
    
    hello("hello", "good", "morning")
    -------------------------------------------
    [TEST]: enter hello()
    hello good morning
    不考虑业务场景,一味的争执技术的高下,都是耍流氓。
  • 相关阅读:
    员工年龄排序之桶排序
    滑动窗口中最大值
    开机自动启动Tomcat
    基于RXTX的串口通讯 windows64位系统可用
    一些SQL
    Java 实现文件上传、下载、打包、文件copy、文件夹copy。
    Page-encoding specified in XML prolog (UTF-8) is different from that specified in page directive (utf-8)
    Java -> 把Excel表格中的数据写入数据库与从数据库中读出到本地 (未完善)
    (转)解决:本地计算机 上的 OracleOraDb10g_home1TNSListener服务启动后停止
    PHP、Java对称加密中的AES加密方法
  • 原文地址:https://www.cnblogs.com/leoych/p/14748809.html
Copyright © 2011-2022 走看看