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

      定义了一个函数,想在运行时动态增加功能,又不想改动函数本身的代码,这就是所谓的装饰器

    例如:

    希望对下列函数调用增加log功能,打印出函数调用:

    def f1(x):
        return x*2
    def f2():
        return x*x
    def f3():
        return x*x*x

    第一种方法,直接修改原函数:

    def f1(x):
        print 'call f1()'
        return x*2
    def f2():
        print'call f2()'
        return x*x
    def f3():
        print 'cal f3()'
        return x*x*x

    第二种方法,利用高阶函数:

    def f1(x):
        return x*2
    def new_fn(f):#装饰器函数
        def fn(x):
            print 'call' +f.__name__+'()'   #__name__为函数对象的属性
            return f(x)
        return fn

    那我们如何调用装饰器了

    第一种方法:

    g1 = new_fn(f1)
    print g1(5)

    第二种方法,f1的原始定义函数被隐藏:

    f1 =new_fn(f1)
    print f1(5)

    python内置的@语法就是为了简化装饰器调用:

    @new_fn
    def f1(x):
        return x*2

    这段的代码就相对于是如下的代码的简写:

    首先定义f1函数,然后通过new_fn这个高阶函数返回了一个新的函数并且这个新的函数并赋值给了f1,原有的f1函数就被彻底的隐藏。

    def f1(x):
        return x*2
    f1 = new_fn(f1)

    装饰器可以极大的简化代码,避免每个函数编写重复性代码,并且装饰器可以打印日志:@long,检查性能:@performance,数据事务:@transaction,url路由:@post('/register')

    完整示例:

    def deco(func):
        def _deco(*args, **kwargs):
            print("before %s called." % func.__name__)
            ret = func(*args, **kwargs)
            print("  after %s called. result: %s" % (func.__name__, ret))
            return ret
        return _deco
     
    @deco
    def myfunc(a, b):
        print(" myfunc(%s,%s) called." % (a, b))
        return a+b
     
    @deco
    def myfunc2(a, b, c):
        print(" myfunc2(%s,%s,%s) called." % (a, b, c))
        return a+b+c
     
    myfunc(1, 2)
    myfunc(3, 4)
    myfunc2(1, 2, 3)
    myfunc2(3, 4, 5)

    结果:

    before myfunc called.
     myfunc(1,2) called.
      after myfunc called. result: 3
    before myfunc called.
     myfunc(3,4) called.
      after myfunc called. result: 7
    before myfunc2 called.
     myfunc2(1,2,3) called.
      after myfunc2 called. result: 6
    before myfunc2 called.
     myfunc2(3,4,5) called.
      after myfunc2 called. result: 12
  • 相关阅读:
    网络面试题-1
    CentOS7下配置Squid代理
    docker使用harbor搭建私有仓库
    docker 基础命令
    docker要隔离的的6种namespace
    python 列表中的数字转为字符串
    python 排列组合
    filter函数
    Pytest配置文件声明自定义用例标识
    pytest参数化
  • 原文地址:https://www.cnblogs.com/Lambda721/p/6128862.html
Copyright © 2011-2022 走看看