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

本文接着对python的装饰器进行思考,本文研究带参数的装饰器的使用方式。普通的装饰器使用的时候,就是个类似@fn的字符串。那么,在本文的讨论中,类似的使用方式是@fn(args)

苏南大叔:python代码,装饰器定义函数可以有几层def?有何区别? - 装饰器有几层def
python代码,装饰器定义函数可以有几层def?有何区别?(图4-1)

大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔和计算机代码的故事。本文描述如何使用带参数的装饰器。测试环境:win10python@3.6.8

单层def可前,没有()

下面这个装饰器非常简单,直接return fn。这个装饰器直接就接收了fn参数,然后返回了一个函数。

两者按理说是不同的函数,可以有不同的逻辑。
def examination(fn):
    print("考试前")
    return fn
@examination
def exam(lang):
    print("考试:" + lang)

苏南大叔:python代码,装饰器定义函数可以有几层def?有何区别? - 一层def
python代码,装饰器定义函数可以有几层def?有何区别?(图4-2)

双层def可前可后,不需要()

下面这个装饰器双层def,第一层接收了参数fn,因为已经返回了个函数,所以@后面不需要()。这里其实出现了一个闭包。

def examination(fn):
    def anything(*args, **kwargs):
        print("苏南大叔考试前")
        fn(*args, **kwargs)
        print("苏南大叔考试后")
    return anything

@examination
def exam(lang):
    print("考试:" + lang)

苏南大叔:python代码,装饰器定义函数可以有几层def?有何区别? - 二层def
python代码,装饰器定义函数可以有几层def?有何区别?(图4-3)

三层def可前可后,可传参数(arg)

这个装饰器有三层def@()返回了一个函数,这个函数接收fn参数,函数内部返回真正的函数逻辑。这里出现了两个闭包。

def examination(arg1):
    def examination(fn):
        def anything(*args, **kwargs):
            print(arg1,"考试前")
            fn(*args, **kwargs)
            print("考试后")
        return anything
    return examination

@examination("sunan")
def exam(lang):
    print("考试:" + lang)

苏南大叔:python代码,装饰器定义函数可以有几层def?有何区别? - 三层def
python代码,装饰器定义函数可以有几层def?有何区别?(图4-4)

分析总结

不知道大家有没有注意到对于@符号后面的字符,有的时候是就仅仅是函数名,没有()。有的时候是(),而且有的时候还带着参数,其实也算是有规律可循的。这里有个检验标准:

  • 装饰器的@语句后面加上(fn),就应该是装饰器定义里面return的函数。
  • return的函数,负责处理fn的具体逻辑。

    定义方式 | 代码层级范例 | 使用方式

一层defddddddddddddddddddddddddddd def dec(fn) return fn@dec
二层defdddddddddd def dec(fn) def logic(a,k) fn(a,k) return logic@dec
三层defdef dec(arg) def dec(fn) def logic(a,k) fn(a,k) return logic@dec(arg)

装饰器函数,首先的任务是必须接收fn参数,然后对这个fn函数进行处理。那么,

  • @符号后面的字符,带不带(),决定于装饰器定义在哪一个层次接收fn
  • 接收fn参数的层次,需要返回一个实际的逻辑处理函数。
  • 处理的逻辑中可以简单加工,返回原函数。
  • 也可以前后任意逻辑处理,并在其中接受函数,执行fn函数,然后return一个函数。
  • 一层def的话,就是直接接收fn,处理后返回原处理函数。
  • 两层def的话,就是第一层接收fn参数,返回第二个def函数,第二层处理被修饰函数的真实参数。
  • 三层def的话,在第一层接收的参数是在@()里面传递的。第二层和第一层的作用同上。

相关链接

综述

更多python程序,请点击苏南大叔的python相关文章。

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

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

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

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