Python 30 天 – 第 13 天 – 装饰器

作者 : 慕源网 本文共2813个字,预计阅读时间需要8分钟 发布时间: 2021-10-12 共100人阅读

Python 30 天 - 第 13 天 - 装饰器

本文是 30 天 Python 挑战系列的一部分。您可以在此处找到本系列之前所有帖子的链接

今天我探索了一个有趣的话题,装饰者。我在 Python 中尝试面向对象编程时确实应用了几个装饰器,例如 @classmethod 和 @staticmethod,但是,当时我没有详细介绍它们。

装饰器是一种编程模式。装饰器只是伪装的函数。

使用装饰器,可以为函数添加更多功能。

我将尝试用我自己的清晰术语来解释它们在底层是如何工作的以及它们为什么有用。

很多很酷的 Python 库都大量使用了装饰器。但是,要理解装饰器,需要了解一些概念。

函数

函数可以像其他数据类型一样分配给变量,也可以像其他值一样作为参数传递给函数。在 JavaScript 中,函数也有类似的行为。

def multiplier(num1, num2):  
  return num1 * num2  
  
some_variable = multiplier # (a reference to the function is created)  
  
del multiplier # (deletes the function)  
  
print(some_variable(2,4)) # 8 (still able to call the function!) 

这种将函数作为值传递的能力对于在 Python 中创建装饰器是必不可少的。

高阶函数

 高阶函数:一个函数可以作为参数传给另外一个函数,或者一个函数的返回值为另外一个函数(若返回值为该函数本身,则为递归),满足其一则为高阶函数。

def logger(func, args):  # higher order function  
    print(f'The result of the passed function is {func(*args)}')  
  
  
def sum(num1, num2):  
    return num1 + num2  
  
  
logger(sum, (1, 5))  

def random()

# 高阶函数defspecial(): print (‘I am something special’) 返回特殊的random_value = random()

def random(): # Higher order function  
  def special():  
    print('I am something special')  
  return special  
  
random_value = random()  
random_value() # I am something special  
# One line way  
random()() # I am something special  
自定义装饰器
def starmaker(func):  
  ''''' 
  A decorator function which accepts a function 
  and then wraps some goodness into it and 
  returns it back! 
  '''  
  def wrapper():  
    func()  
    print('You are a star now!')  
    print('*********')  
  return wrapper  
 
@starmaker  
def layman():  
  print('I am just a layman')  
  
layman()  

装饰类中函数的starmaker 装饰器,给layman 函数增加功能

装饰器@starmaker可以添加到任何函数之上,该函数将会print (‘You are a star now!’)

Python 装饰器识别@decoratorname 并实时将其转换为函数并进行处理。上面的代码与下面的代码块完全相似,没有使用@decorator 语法

def starmaker(func):  
  ''''' 
  A decorator function which accepts a function 
  and then wraps some goodness into it and 
  returns it back! 
  '''  
  def wrapper():  
    func()  
    print('You are a star now!')  
    print('*********')  
  return wrapper  
  
def layman():  
  print('I am just a layman')  
  
starmaker(layman)() # This is the underlying decorator magic!  

如果我们将它与 JavaScript 进行比较,那么 JavaScript 没有装饰器作为语言的一部分。但是,作为 JavaScript 超集的 TypeScript 具有装饰器的这个概念。像 Angular、NestJs 这样的框架严重依赖装饰器。

装饰器函数也可以接受参数,并且可以根据传递的参数进行自定义。

def emojifier(func):  
  def wrapper(emoji):  
    # kwags are keyword arguments  
    print(emoji)  
    func()  
  return wrapper  
 
@emojifier  
def random():  
  pass  
  
random('😀') # 😀  

为什么装饰器很有用?

装饰器是一种重要的编程模式,如果使用得当,可以提供很多好处。它使代码非常可重用,并将添加的功能绑定到函数。

# Create an @authenticated decorator that only allows   
# the function to run is user1 has 'valid' set to True:  
test_user = {  
    'name': 'Jackson',  
    'valid': True  
}  
  
another_user = {  
  'name': 'Nathan',  
  'valid': False  
}  
  
def authenticated(fn):  
  def wrapper(*args, **kwargs):  
    if args[0]['valid']:  
      fn(args)  
  return wrapper  
 
@authenticated  
def message_friends(user):  
    print('message has been sent')  
  
message_friends(test_user) # message has been sent  
message_friends(another_user) # (Does nothing)  

上述认证的装饰器函数仅根据指定的条件调用 message_friends 函数。这提供了很大的灵活性,并根据用户的身份验证状态执行条件操作。

这就是今天的全部内容。明天我将探讨 另一个重要的话题 Python 中的异常处理。


慕源网 » Python 30 天 – 第 13 天 – 装饰器

常见问题FAQ

免费下载或者VIP会员专享资源能否直接商用?
本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。

发表评论

开通VIP 享更多特权,建议使用QQ登录