
正文
关于python函数修饰器的信息
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
python函数修饰符@的使用
python函数修饰符@ 修饰符 ‘@’符号用作函数修饰符是python2.4新增加的功能,修饰符必须出现在函数定义前一行,不允许和函数定义在同一行。也就是说@A def f(): 是非法的。 只可以在模块或类定义层内对函数进行修饰,不允许修修饰一个类。一个修饰符就是一个函数,它将被修饰的函数做为参数,并返回修饰后的同名函数或其它可调用的东西。 本质上讲,装饰符@类似于 回调函数 ,把其它的函数(暂且称为目的参数,后面紧接着的函数)作为自己的入参,在目的函数执行前,执行一些自己的操作, 比如:计数、打印一些提示信息等,然后返回目的函数。下面列举一个简单的例子。
创建函数修饰符的规则:
(1)修饰符是一个函数
(2)修饰符取被修饰函数为参数
(3)修饰符返回一个新函数
(4)修饰符维护被维护函数的签名
例子1: 被修饰函数不带参数
运行结果:
例子2: 使用functools模块提供的修改函数属性的方法wraps
运行结果:
可见test1的函数名称变了,如果某些代码用到就会出问题,可以使用functools模块提供的修改函数属性的方法wraps
运行结果:
例子3: 被修饰函数带参数
运行结果:
例子4: 修饰符带参数 ,需要比上面例子多一层包装
运行结果:
相关问答
Q1: Python中的“ @”(@)符号有什么作用?
【@】符号在python中是装饰器的意思。
装饰器对一个可调用对象(函数、方法、类等等)进行装饰,它返回的也是一个可调用对象。
一般情况下,装饰器是对被装饰对象的修饰与增强。用现实事物类比的话,可以类比为中间商:中间商不生产产品,它将工厂生产的产品进行包装、运输后再销售给顾客。装饰器不实现核心功能,它提供对目标函数调用的封装与强。
它装饰的方法返回值是一个对象(BillList、Bill、List[BillDetail]等),而装饰器【enabled_cache】的作用如它的名称一样:使用缓存。可以看到,这个装饰器函数中定义了一个函数【wrapper】然后将这个wrapper作为返回值。这样,原本调用ProductionBos.bill_with_last_week的代码就不需要做任何改变就能享受到ProductionBos.bill_with_last_week原有的功能(得到一个BillList对象)和enabled_cache提供的附加功能(如果该对象有缓存,就不再从数据库查询)。
Q2: Python嵌套函数和闭包
在Python语言中python函数修饰器,可以在函数中定义函数。 这种在函数中嵌套定义的函数也叫内部函数。我们来看下面的代码:
上述代码中,定义python函数修饰器了函数greet,在函数greet内部又定义了一个函数inner_func, 并调用该函数打印了一串字符。
我们可以看到,内部函数inner_func的定义和使用与普通函数基本相同。需要注意的是变量的作用域,在上述代码中,函数参数name对于全局函数greet是局部变量,对内部函数inner_func来说则是非局部变量。内部函数对于非局部变量的访问规则类似于标准的外部函数访问全局变量。
从这个例子我们还可以看到内部函数的一个作用,就是通过定义内部函数的方式将一些功能隐藏起来,防止外部直接调用。常见的场景是,在一个复杂逻辑的函数中,将一些小的任务定义成内部函数,然后由这个外层函数使用,这样可以使代码更为清晰,易于维护。这些内部函数只会在这个外层函数中使用,不能被其他函数或模块使用。
在Python语言中, 函数也是对象,它可以被创建、赋值给变量,或者作为函数的返回值。我们来看下面这个例子。
在上述代码中,在函数gen_greet内部定义了inner_func函数,并返回了一个inner_func函数对象。外部函数gen_greet返回了一个函数对象,所以像gen_greet这样的函数也叫工厂函数。
在内部函数inner_func中,使用了外部函数的传参greet_words(非局部变量),以及函数的参数name(局部变量),来打印一个字符串。
接下来,调用gen_greet("Hello")创建一个函数对象say_hello,紧接着调用say_hello("Mr. Zhang"),输出的结果为:Hello, Mr. Zhang!
同样的,调用gen_greet("Hi")创建一个函数对象say_hi,调用say_hello("Mr. Zhang"),输出的结果为:Hi,Tony!
我们可以发现,gen_greet返回的函数对象具有记忆功能,它能够把所需使用的非局部变量保存下来,用于后续被调用的时候使用。这种保存了非局部变量的函数对象被称作闭包(closure)。
那么闭包是如何实现的呢python函数修饰器?其实并不复杂,函数对象中有一个属性__closure__,它就是在创建函数对象时用来保存这些非局部变量的。
__closure__属性是一个元组或者None类型。在上述代码中,我们可以通过下面方式查看:
函数的嵌套所实现的功能大都可以通过定义类的方式来实现,而且类是更加面向对象的代码编写方式。
嵌套函数的一个主要用途是实现函数的装饰器。我们看下面的代码:
在上述代码中,logger函数返回函数with_logging,with_logging则是打印了函数func的名称及传入的参数,然后调用func, 并将参数传递给func。其中的@wraps(func)语句用于复制函数func的名称、注释文档、参数列表等等,使得with_logging函数具有被装饰的函数func相同的属性。
代码中接下来用@logger对函数power_func进行修饰,它的作用等同于下面的代码:
可见,装饰器@符其实就是上述代码的精简写法。
通过了解了嵌套函数和闭包的工作原理,我们在使用过程中就能够更加得心应手了。
Q3: python中修饰器是什么?
就是一个callable object。 它使python编程更加容易。
例如:
@dec
def A(args):
pass
它就等价于dec(A). 当然还有带参数的decorator。我就不举例了。
python文档里有这样一句话。
A function definition may be wrapped by one or more decorator expressions. Decorator expressions are evaluated when the function is defined, in the scope that contains the function definition. The result must be a callable, which is invoked with the function object as the only argument. The returned value is bound to the function name instead of the function object. Multiple decorators are applied in nested fashion.
大概就是说函数的定义可以用多个decorator。decorator就在函数定义时用函数作为参数调用,然后返回一个可调用对象。 所以写decorator的时候一定要返回一个可调用对象。
不知道你明白没。
关于python函数修饰器和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。






