当前位置: 首页 > 编程笔记 >

python中的装饰器详解

唐法
2023-03-14
本文向大家介绍python中的装饰器详解,包括了python中的装饰器详解的使用技巧和注意事项,需要的朋友参考一下

在了解装饰器的之前一定要先了解函数作为参数传递, 什么是函数内嵌,请参考我之前写的博客函数简介

因为在python里面,函数也是对象,也可以作为参数进行传递.python装饰器本质也是一种特殊函数,它接收的参数是函数对象,然后动态地函数参数添加额外的功能,而不用修改原有的函数对象.python装饰器传入的参数是函数,返回的值也是函数!
python装饰器思想有点类似设计模式的装饰模式, 其意图是动态地给函数对象添加额外的功能.比如像增加日志打印的功能,有点面向切面编程(AOP)的感觉.
装饰器语法

以@开头,接着后面跟着的是装饰器的名字和可选的参数.装饰器语法是一种语法糖.
格式如下


@decomaker(deco_args)

    def foo(func_opt_args)


可以组合,等价于foo = g(f(foo))

@g

@f

def foo():

    statement


简单装饰器

实例


#!/usr/bin/python

def  deco(func):

    print 'start'

    func()

    print 'end'

    return func

@deco def foo():     print 'In foo'

foo() foo()


输出

start

In foo

end

In foo

In foo


带内嵌函数装饰器

内嵌函数保证每次新函数都被调用.而且被装饰的函数可以带有参数.
实例


def  deco(func):

    def _deco(x):    #该函数为内嵌函数

        print 'start'

        func(x)

        print 'end' 

    return _deco

@deco def foo(x):     print 'In foo, get value is: %d' % x

foo(123456)


输出:

start

In foo, get value is: 123456

end


带参数的装饰器

需要自己返回以函数作为参数的装饰器。换句话说,decomaker()用 deco_args 做了些事并返回函数对象,而该函数对象正是以 foo 作为其参数的装饰器。简单的说来:foo=decomaker(deco_args)(foo)

实例


def deco(arg):

    def wrapper1(func):

        def _deco(x):

            print "get type is: ", arg

            func(x)

        return _deco

    def wrapper2(func):         def _deco(x):             func(x)             print "get type is: ", arg         return _deco

    if arg == 'type1':         return wrapper1     else:         return wrapper2

@deco("type2") def foo(x):     print 'In foo: ', x

foo(123)


输出

In foo:  123

get type is:  type2


总结

装饰器本质是高阶的函数,可以装饰其他函数,增加被装饰函数的功能,但不能覆盖或改变被装饰函数原有的行为.对于被装饰的函数来说,装饰器是透明的.装饰器传入参数为函数,返回的函数是被装饰的函数.最后我们来实现给一个函数添加打印日志的功能,而不用改变这个函数.


#!/usr/bin/python

#coding=utf-8

import functools

def log(prefix, suffix):     def deco(func):         @functools.wraps(func)         def wrapper(*args, **kargs):             print '%s log start' % prefix             print('get a is: %s' % args[0])             print('get b is: %s' % args[1])             print('get c is: %s' % args[2])             print('get d is: %s' % kargs['d'])             print('get d is: %s' % kargs['f'])             func(*args, **kargs)             print '%s log end' % suffix         return wrapper     return deco

@log('logstart', 'logend') def test(a, b, c, d, f):     print 'call func name is: %s' % test.__name__

test(1, 2, 3, d = 'dddd', f = 'ffff')


输出:

logstart log start

get a is: 1

get b is: 2

get c is: 3

get d is: dddd

get d is: ffff

call func name is: test

logend log end

 类似资料:
  • 本文向大家介绍python装饰器实例大详解,包括了python装饰器实例大详解的使用技巧和注意事项,需要的朋友参考一下 一.作用域 在python中,作用域分为两种:全局作用域和局部作用域。  全局作用域是定义在文件级别的变量,函数名。而局部作用域,则是定义函数内部。  关于作用域,我们要理解两点:     a.在全局不能访问到局部定义的变量     b.在局部能够访问到全局定义的变量,但是不能修

  • 问题内容: 我想构造用作装饰器的类,并保留以下原则: 应该有可能在top 1函数上堆叠多个此类装饰器。 产生的函数名称指针应该与没有装饰器的相同函数没有区别,可能只是它是哪种类型/类。 除非装饰员实际要求,否则订购装饰员应该无关紧要。就是 独立的装饰器可以以任何顺序应用。 这是针对Django项目的,现在我正在处理的特定情况下,该方法需要2个装饰器,并显示为普通的python函数: @AutoTe

  • 问题内容: 我正在尝试学习装饰器。我了解它的概念,现在尝试实现它。 这是我编写 的代码,代码不言自明。它只是检查参数是否传入。 抛出错误的说法。我了解它未在下定义,但不知道如何纠正此代码?我要去哪里错了? 问题答案: 您的装饰器应如下所示: 需要注意的几点: 期望将类作为第一个参数(您可以将其替换为简单的try / except TypeError除外)。 包装器应返回一个函数,而不是被调用函数的

  • 本文向大家介绍详解Python装饰器由浅入深,包括了详解Python装饰器由浅入深的使用技巧和注意事项,需要的朋友参考一下 装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码。装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们以装饰函数为例子介绍其用法。要理解在Python中装饰器的原理,需要一步一步

  • 本文向大家介绍详解python中的生成器、迭代器、闭包、装饰器,包括了详解python中的生成器、迭代器、闭包、装饰器的使用技巧和注意事项,需要的朋友参考一下 迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。 1|1可迭代对象 以直接作用于 for 循环的数据类型有以下几种: 一类是集合数

  • 本文向大家介绍Python装饰器的函数式编程详解,包括了Python装饰器的函数式编程详解的使用技巧和注意事项,需要的朋友参考一下 Python的装饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西。虽然好像,他们要干的事都很相似——都是想要对一个已有的模块做一些“修饰工作”,所谓修饰工作就