装饰器

Java注解和python装饰器

java注解:

  • 都是@开头,注解、装饰器都可以自定义、都可以带参数、都可以被标注代码块之前执行

  • Java 注解也叫元数据,一种代码级别的说明。注解是给别人看的,功能不仅仅由注解决定

  • 注解对元数据进行了检查、对比等工作,不会对所修饰的代码产生直接的影响

  • java注解可以写在类、方法、变量头上

  • 使用注解(Annotation)的语言:AtScript、Java、C#(叫 Attribute)

python装饰器:

  • 都是@开头,注解、装饰器都可以自定义、都可以带参数、都可以被标注代码块之前执行

  • Python 装饰器是一种语法糖。装饰器直接拦截,直接改变被装饰对象的行为

  • 装饰器可以对方法进行功能上的改变,可以对所修饰的代码产生直接的影响。

  • python装饰器可以写在类、方法头上。

  • 使用装饰器(Decorator)的语言:Python、JavaScript/ECMAScript

在java中注解+反射能够实现和python里装饰器同样的效果。

 

装饰器基础概念

装饰器本质上是一个函数,它可以接收一个函数作为参数并返回一个新的函数。这个新函数是对原函数的一种包装或增强,可以在不改变原函数代码的前提下,增加额外的功能。

装饰器的返回值也是一个函数。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。

Python中的装饰器是一个语法糖,它本身就涉及到一个返回函数的概念,可以说返回函数是装饰器得以实现的基石。

由于Python有一个内建属性__call__,这个是一个很神奇的特性,只要某个类型中有__call__方法,我们可以把这个类型的对象当作函数来使用。这点是JavaC++不一样的地方,Python 中的函数可以像普通变量一样当做参数传递给另外一个函数

装饰器实现

装饰器的实现程可以分为以下几个步骤:

  1. 定义装饰器:首先定义一个装饰器函数,该函数接收一个函数作为参数。

  2. 定义包装函数:在装饰器函数内部,定义一个包装函数(wrapper),这个包装函数会调用原函数,并可以在调用前后添加额外的逻辑。

  3. 返回包装函数:装饰器函数返回这个包装函数。

  4. 使用@语法:在需要被装饰的函数定义前使用@符号加上装饰器名称,这样Python解释器会自动将这个函数作为参数传递给装饰器,并将返回的新函数(包装函数)赋值给原函数名。

说白了装饰器就是一个闭包函数。

def deco(func):
   def _deco():
       print("before myfunc() called.")
       # 执行被装饰的函数
       func()
       print(" after myfunc() called.")
       # 不需要返回func,实际上应返回原函数的返回值
   return _deco

@deco
def myfunc():
   print(" myfunc() called.")

myfunc()

示例:

1、装饰器装饰的函数有多个参数

def deco(func):
   # 内部参数需要定义 不定数量的位置参数和关键字参数,以接受和传递任意数量的参数
   def _deco(*args, **kwargs):
       print("before %s called." % func.__name__)
       # 执行被装饰的函数,使用不定参数
       ret = func(*args, **kwargs)
       print(" after %s called. result: %s" % (func.__name__, ret))
       return ret
   return _deco

@deco
def myfunc(a, b, c):
   print(" myfunc(%s,%s,%s) called." % (a, b, c))
   return a+b+c

myfunc(1, 2, 3)

2、装饰器带参数:装饰器带参数,则装饰器函数则变成了三层,我们需要在最外层把装饰器的参数传递进去。

# 第一层传入装饰器参数
def deco(arg):
   # 第二层传入被装饰函数
   def _deco(func):
       # 第三层进行逻辑处理
       def __deco():
           print("before %s called [%s]." % (func.__name__, arg))
           func()
           print(" after %s called [%s]." % (func.__name__, arg))
       return __deco
   return _deco

@deco("mymodule")
def myfunc():
   print(" myfunc() called.")
 
myfunc()

 

posted @ 2024-10-14 19:55  hjy1995  阅读(16)  评论(0编辑  收藏  举报