📜  在Python中调试装饰器

📅  最后修改于: 2022-05-13 01:54:18.618000             🧑  作者: Mango

在Python中调试装饰器

Python中的装饰器确实是一个非常强大的功能。如果您是一名 Web 开发人员,并且您使用过 Django 框架甚至其他一些开发框架,那么您可能已经遇到过装饰器。

概述装饰器是包装现有函数或方法并修改其功能的包装函数。让我们举一个简短的例子。假设您有一个 speak函数,它返回一个中性消息

Python3
def speak():
    """Returns a neutral message"""
    return "Hi, Geeks!"
  
# printing the output
print(speak())


Python3
# decorator
def make_geek_happy(func):
    def wrapper():
        neutral_message = func()
        happy_message = neutral_message + " You are happy!"
        return happy_message
    return wrapper
  
#using the decorator 
@make_geek_happy
def speak():
    """Returns a neutral message"""
    return "Hi, Geeks!"
  
print(speak())


Python3
# decorator
def make_geek_happy(func):
    def wrapper():
        neutral_message = func()
        happy_message = neutral_message + " You are happy!"
        return happy_message
    return wrapper
  
def speak():
    """Returns a neutral message"""
    return "Hi!"
  
  
# wrapping the function in the decorator
# and assigning it to positive_message
positive_message = make_geek_happy(speak)
  
print(positive_message())
  
print(speak.__name__) 
print(speak.__doc__) 
print(positive_message.__name__)
print(positive_message.__doc__)


Python3
# importing the module
import functools
  
# decorator
def make_geek_happy(func):
    @functools.wraps(func)
    def wrapper():
        neutral_message = func()
        happy_message = neutral_message + " You are happy!"
        return happy_message
    return wrapper
  
def speak():
    """Returns a neutral message"""
    return "Hi!"
  
positive_message = make_geek_happy(speak)
print(positive_message())
  
print(speak.__name__) 
print(speak.__doc__) 
print(positive_message.__name__)
print(positive_message.__doc__)


输出:

Hi, Geeks!

假设您需要修改函数以愉快的语气返回消息。所以让我们为此创建一个装饰器。

Python3

# decorator
def make_geek_happy(func):
    def wrapper():
        neutral_message = func()
        happy_message = neutral_message + " You are happy!"
        return happy_message
    return wrapper
  
#using the decorator 
@make_geek_happy
def speak():
    """Returns a neutral message"""
    return "Hi, Geeks!"
  
print(speak())

输出:

Hi, Geeks! You are happy!

调试装饰器

这样,装饰器也可以用来修改不同的功能,使它们更有用。然而,这个过程有一些缺点。当我们将原始函数包装在装饰器中时,原始函数的元数据会丢失。考虑下面的程序,但这次我们以另一种方式使用装饰器只是为了让你理解。

如果您尝试访问 positive_message函数的任何元数据,它实际上会返回装饰器内包装器的元数据。

Python3

# decorator
def make_geek_happy(func):
    def wrapper():
        neutral_message = func()
        happy_message = neutral_message + " You are happy!"
        return happy_message
    return wrapper
  
def speak():
    """Returns a neutral message"""
    return "Hi!"
  
  
# wrapping the function in the decorator
# and assigning it to positive_message
positive_message = make_geek_happy(speak)
  
print(positive_message())
  
print(speak.__name__) 
print(speak.__doc__) 
print(positive_message.__name__)
print(positive_message.__doc__)

输出:

Hi! You are happy!
speak
Returns a neutral message
wrapper
None

这些结果使调试变得非常困难。但是多亏了Python ,它也有一个解决方案可以轻松解决这个问题。我们只需要使用Python标准库中包含的functools.wraps()装饰器。

这是一个例子:

Python3

# importing the module
import functools
  
# decorator
def make_geek_happy(func):
    @functools.wraps(func)
    def wrapper():
        neutral_message = func()
        happy_message = neutral_message + " You are happy!"
        return happy_message
    return wrapper
  
def speak():
    """Returns a neutral message"""
    return "Hi!"
  
positive_message = make_geek_happy(speak)
print(positive_message())
  
print(speak.__name__) 
print(speak.__doc__) 
print(positive_message.__name__)
print(positive_message.__doc__)

输出:

Hi! You are happy!
speak
Returns a neutral message
speak
Returns a neutral message