python装饰器@property

装饰器示例

def w1(func):
    def inner():
        print(‘...验证权限...‘)
        func()

    return inner

@w1
def f1():
    print(‘f1 called‘)

@w1
def f2():
    print(‘f2 called‘)

f1()
f2()

输出结果:

...验证权限...
f1 called
...验证权限...
f2 called

当调用f1,f2函数时,首先执行了验证。通过一个闭包函数w1,调用函数上通过关键词@w1,对f1,f2完成了装饰。

当python解释器解释@w1时,会调用w1函数,同时将被修饰函数名传入(例如f1),在执行w1函数的时候,直接把inner函数返回了,同事把它赋值给f1,此时的f1已经不是未加修饰的f1了,而是指向了w1.inner函数地址。再调用f1函数,就好先执行权限验证,然后调用原来的f1(),该处的f1是通过参数传进来的f1.

执行时机

def w1(fun):
    print(‘...装饰器开始装饰...‘)

    def inner():
        print(‘...验证权限...‘)
        fun()

    return inner

@w1
def test():
    print(‘test‘)

test()

输出结果:

...装饰器开始装饰...
...验证权限...
test

由此可见,执行@w1时相当于执行了如下代码:

test = w1(test)

两个装饰器执行流程和修饰结果

def makeBold(fun):
    print(‘----a----‘)

    def inner():
        print(‘----1----‘)
        return ‘<b>‘ + fun() + ‘</b>‘

    return inner

def makeItalic(fun):
    print(‘----b----‘)

    def inner():
        print(‘----2----‘)
        return ‘<i>‘ + fun() + ‘</i>‘

    return inner

@makeBold
@makeItalic
def test():
    print(‘----c----‘)
    print(‘----3----‘)
    return ‘hello python decorator‘

ret = test()
print(ret)

输出结果:

----b----
----a----
----1----
----2----
----c----
----3----
<b><i>hello python decorator</i></b>

可以发现,先用第二个装饰器(makeItalic)进行装饰,接着再用第一个装饰器(makeBold)进行装饰,而在调用过程中,先执行第一个装饰器(makeBold),接着再执行第二个装饰器(makeItalic)。

对有参数函数进行装饰

def w_say(fun):
    """
    如果原函数有参数,那闭包函数必须保持参数个数一致,并且将参数传递给原方法
    """

    def inner(name):
        """
        如果被装饰的函数有行参,那么闭包函数必须有参数
        :param name:
        :return:
        """
        print(‘say inner called‘)
        fun(name)

    return inner

@w_say
def hello(name):
    print(‘hello ‘ + name)

hello(‘wangcai‘)

输出结果:

say inner called
hello wangcai

多个参数或不定个参数

def w_add(func):
    def inner(*args, **kwargs):
        print(‘add inner called‘)
        func(*args, **kwargs)

    return inner

@w_add
def add(a, b):
    print(‘%d + %d = %d‘ % (a, b, a + b))

@w_add
def add2(a, b, c):
    print(‘%d + %d + %d = %d‘ % (a, b, c, a + b + c))

add(2, 4)
add2(2, 4, 6)

输出结果:

add inner called
2 + 4 = 6
add inner called
2 + 4 + 6 = 12

对带返回值的函数进行修饰

def w_test(func):
    def inner():
        print(‘w_test inner called start‘)
        func()
        print(‘w_test inner called end‘)
    return inner

@w_test
def test():
    print(‘this is test fun‘)
    return ‘hello‘

ret = test()
print(‘ret value is %s‘ % ret)

输出结果:

w_test inner called start
this is test fun
w_test inner called end
ret value is None

可以发现,此时,并没有输出test函数的‘hello’,而是None,那是为什么呢,可以发现,在inner函数中对test进行了调用,但是没有接受不了返回值,也没有进行返回,那么默认就是None了,知道了原因,那么来修改一下代码:

def w_test(func):
    def inner():
        print(‘w_test inner called start‘)
        str = func()
        print(‘w_test inner called end‘)
        return str

    return inner

@w_test
def test():
    print(‘this is test fun‘)
    return ‘hello‘

ret = test()
print(‘ret value is %s‘ % ret)

输出结果:

w_test inner called start
this is test fun
w_test inner called end
ret value is hello

带参数的装饰器

def func_args(pre=‘xiaoqiang‘):
    def w_test_log(func):
        def inner():
            print(‘...记录日志...visitor is %s‘ % pre)
            func()

        return inner

    return w_test_log

# 带有参数的装饰器能够起到在运行时,有不同的功能

# 先执行func_args(‘wangcai‘),返回w_test_log函数的引用
# @w_test_log
# 使用@w_test_log对test_log进行装饰
@func_args(‘wangcai‘)
def test_log():
    print(‘this is test log‘)

test_log()

输出结果:

...记录日志...visitor is wangcai
this is test log

通用装饰器

def w_test(func):
    def inner(*args, **kwargs):
        ret = func(*args, **kwargs)
        return ret

    return inner

@w_test
def test():
    print(‘test called‘)

@w_test
def test1():
    print(‘test1 called‘)
    return ‘python‘

@w_test
def test2(a):
    print(‘test2 called and value is %d ‘ % a)

test()
test1()
test2(9)

输出结果:

test called
test1 called
test2 called and value is 9 

类装饰器

装饰器函数其实是一个接口约束,它必须接受一个callable对象作为参数,然后返回一个callable对象。

在python中,一般callable对象都是函数,但是也有例外。比如只要某个对象重写了call方法,那么这个对象就是callable的。

当创建一个对象后,直接去执行这个对象,那么是会抛出异常的,因为他不是callable,无法直接执行,但进行修改后,就可以直接执行调用了,如下

class Test(object):
    def __call__(self, *args, **kwargs):
        print(‘call called‘)

t = Test()
print(t())

下面,引入正题,看一下如何用类装饰函数。

class Test(object):
    def __init__(self, func):
        print(‘test init‘)
        print(‘func name is %s ‘ % func.__name__)
        self.__func = func

    def __call__(self, *args, **kwargs):
        print(‘装饰器中的功能‘)
        self.__func()

@Test
def test():
    print(‘this is test func‘)

test()

输出结果:

test init
func name is test
装饰器中的功能
this is test func

和之前的原理一样,当python解释器执行到到@Test时,会把当前test函数作为参数传入Test对象,调用init方法,同时将test函数指向创建的Test对象,那么在接下来执行test()的时候,其实就是直接对创建的对象进行调用,执行其call方法。

原文地址:https://www.cnblogs.com/xiaoaofengyue/p/9025180.html

时间: 2024-11-10 14:57:38

python装饰器@property的相关文章

python学习之类和实例的属性;装饰器@property

无论是类还是实例,一切皆是对象. Python是强动态语言,和java在这点上有所不同. class Ab(): a = 666 # 定义类对象Ab,自带属性a,值为666 # 使用Ab.__dict__可以查看类Ab的属性 us1 = Ab() us2 = Ab() # 定义两个实例对象us1.us2,这两个实例自身并不具备任何属性 # 只有在__init__中定义了self.arg=xxx的情况下,实例默认会具备arg属性 动态语言中,属性自带操作方法:获取(读).设置(写):还可以定义删除

python 之用装饰器@property,把方法变成一个特性

# -*- coding: utf-8 -*- """ Created on Sun Nov 13 23:19:03 2016 @author: toby """ #知识点:用装饰器@property,把方法变成一个特性 class Province:     memo = 'One of China\'s 23 provinces' #静态字段          def __init__(self,name,capital,leadership

python装饰器Decorators

http://blog.csdn.net/pipisorry/article/details/41902599 Introduction 装饰器Decorators是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能.装饰器用于在不改变原函数代码的情况下修改已存在的函数.常见场景是增加一句

Python装饰器的学习笔记(转载)

Python装饰器的学习笔记 2017-05-18 程序员共读 来自:标点符的<Python装饰器的学习笔记> 链接:http://www.biaodianfu.com/python-decorator.html 原文:http://stackoverflow.com/questions/739654/how-to-make-a-chain-of-function-decorators-in-python#answer-1594484 装饰器(decorator)是一种高级Python语法.可

Python——装饰器基础

装饰器基础 前面快速介绍了装饰器的语法,在这里,我们将深入装饰器内部工作机制,更详细更系统地介绍装饰器的内容,并学习自己编写新的装饰器的更多高级语法. ================================================================================= 什么是装饰器 装饰是为函数和类指定管理代码的一种方式.Python装饰器以两种形式呈现: [1]函数装饰器在函数定义的时候进行名称重绑定,提供一个逻辑层来管理函数和方法或随后对它们的调

Python装饰器完全解读

1 引言 装饰器(Decorators)可能是Python中最难掌握的概念之一了,也是最具Pythonic特色的技巧,深入理解并应用装饰器,你会更加感慨——人生苦短,我用Python. 2 初步理解装饰器 2.1 什么是装饰器 在解释什么是装饰器之前,我们有必要回顾一下Python中的一些思想和概念.我们都知道,Python是一门面向对象的语言,Python基本思想就是一些皆对象,数据类型是对象.类是对象.类实例也是对象……对于接下来我们要说的装饰器而言,最重要的是,函数也是对象! 你没看错,函

Python装饰器详解,详细介绍它的应用场景

装饰器的应用场景 附加功能 数据的清理或添加: 函数参数类型验证 @require_ints 类似请求前拦截 数据格式转换 将函数返回字典改为 JSON/YAML 类似响应后篡改 为函数提供额外的数据 mock.patch 函数注册 在任务中心注册一个任务 注册一个带信号处理器的函数 不同应用场景下装饰器实现 函数注册表 简单注册表 funcs = [] def register(func): funcs.append(func) return func @register def a(): r

5.初识python装饰器 高阶函数+闭包+函数嵌套=装饰器

一.什么是装饰器? 实际上装饰器就是个函数,这个函数可以为其他函数提供附加的功能. 装饰器在给其他函数添加功能时,不会修改原函数的源代码,不会修改原函数的调用方式. 高阶函数+函数嵌套+闭包 = 装饰器 1.1什么是高阶函数? 1.1.1函数接收的参数,包涵一个函数名. 1.1.2 函数的返回值是一个函数名. 其实这两个条件都很好满足,下面就是一个高阶函数的例子. def test1(): print "hamasaki ayumi" def test2(func): return t

python装饰器通俗易懂的解释!

python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说明一下: 小P闲来无事,随便翻看自己以前写的一些函数,忽然对一个最最最基础的函数起了兴趣: 1 def sum1(): 2 sum = 1 + 2 3 print(sum) 4 sum1() 此时小P想看看这个函数执行用了多长时间,所以写了几句代码插进去了: 1 import time 2 3 def