我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

在上一篇文章中,苏南大叔已经总结了装饰器定义的几种形式,主要有三个层次的定义方式。那么,这些定义方式可不可以定义到类里面呢?但是,主要的写法还是函数类似的写法。那么,python装饰器可以定义在类里面么?这就是本文中要重点讨论的问题。

苏南大叔:python代码,多个装饰器定义到一个类里面后,如何使用? - 多个装饰器定义到一个类里面后,如何使用
python代码,多个装饰器定义到一个类里面后,如何使用?(图6-1)

大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔和计算机代码的故事。本文展示装饰器功能和类之间的功能联系。本文测试环境:win10python@3.6.8

基本思路

装饰器定义为函数的时候,可以写好几层。其中定义为三层的时候,就可以在装饰器里面传递为参数。如果这个类似的事情,到类里面的时候,传递参数的功能就可以放到类初始化__init__的时候。

那么,对应的装饰器在使用的时候,就应该写成@class().method或者@class().method()。然而,这种写法目前在python里面是不符合语法报错的,报错信息是SyntaxError: invalid syntax。如下图所示:

苏南大叔:python代码,多个装饰器定义到一个类里面后,如何使用? - 错误信息提示
python代码,多个装饰器定义到一个类里面后,如何使用?(图6-2)

那么,到底如何才能把装饰器定义到python的类里面呢?又是如何使用的呢?

在本文测试代码中,在examination类中,一共定义了三个装饰器。分别是__call__/call/call2。然后代码的尾部,对这个类进行了初始化,实例是decoration

class examination(object):
    def __init__(self, who):
        self.who = who
    
    def __call__(self, fn):
        def anything(*args, **kwargs):
            print(self.who, "说1:")
            fn(*args, **kwargs)
        return anything

    def call(self, fn):
        def anything(*args, **kwargs):
            print(self.who, "说2:")
            fn(*args, **kwargs)
        return anything

    def call2(self, arg1):
        def a(fn):
            def anything(*args, **kwargs):
                print(self.who, "["+arg1+"] 说3:")
                fn(*args, **kwargs)
            return anything
        return a

decoration = examination("sunan")

苏南大叔:python代码,多个装饰器定义到一个类里面后,如何使用? - 代码定义类
python代码,多个装饰器定义到一个类里面后,如何使用?(图6-3)

单装饰器独占一个类

装饰器定义在类中,定义为类的__call__方法。但是,这个情况下,一个类只能定义一个装饰器。默认自动调用了__call__()方面,实际上是把类转成了函数。

@examination("sunan")
def exam(lang):
    print("参加了考试"+lang)
exam("日本语")

苏南大叔:python代码,多个装饰器定义到一个类里面后,如何使用? - __call__方法
python代码,多个装饰器定义到一个类里面后,如何使用?(图6-4)

多个装饰器同一个类

可以把多个装饰器定义到一个类中,但是使用的时候,目前是因为python语法的限制,没有办法直接使用。需要做个迂回的战术。在上一个例子里面,其实是使用了一个小技巧,使用了类里面默认调用的__call__方法,骗过了语法检测。那么,在这个例子中,因为各个方法并不是默认的__call__方法,所以这里就不能这么使用了。

这些定义在类里面的装饰器使用方法如下:

@decoration.call
def exam(lang):
    print("参加了考试"+lang)
exam("日本语")

@decoration.call2("su")
def exam(lang):
    print("参加了考试"+lang)
exam("韩语")

苏南大叔:python代码,多个装饰器定义到一个类里面后,如何使用? - 代码调用2
python代码,多个装饰器定义到一个类里面后,如何使用?(图6-5)

多个装饰器同一个类,模块中初始化

装饰器的定义还是上面的那个类,把这些测试代码放到一个模块module.py文件里面。然后在另外一个文件中引入这个模块,使用方式上很简单,就是在上面的基础上,再加上模块.字样即可。

调用者文件test.py

import module
@module.decoration.call
def exam(lang):
    print("参加了考试"+lang)
exam("日本语")

@module.decoration.call2("su")
def exam(lang):
    print("参加了考试"+lang)
exam("韩语")

苏南大叔:python代码,多个装饰器定义到一个类里面后,如何使用? - 模块化使用
python代码,多个装饰器定义到一个类里面后,如何使用?(图6-6)

相关文章

综述

本文是python装饰器系列文章中的一篇文章,主要致力于说明装饰器和类的关系。更多python经验文章,请点击:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python