在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