Python Tricks : How to Write Debuggable Decorators

简介: Python Tricks : How to Write Debuggable Decorators

Python Tricks: How to Write “Debuggable” Decorators
When you use a decorator, really what you’re doing is replacing one funciton with another. One downside of this process is that it “hides” some of the metadata attached to the original(undecorated) function.

For example, the original function name, its doctoring, and parameter list are hidden by the wrapper closure:

In [4]: def uppercase(func):
   ...:     def wrapper():
   ...:         original_result = func()
   ...:         modified_result = original_result.upper()
   ...:         return modified_result
   ...:     return wrapper
In [1]: def greet():
   ...:     """Return a friendly greeting."""
   ...:     return 'Hello!'

In [2]: decorated_greet = uppercase(greet)

If you try to access any of that function metadata, you’ll see the wrapper closure’s metadata instead:

In [6]: greet.__name__
Out[6]: 'greet'

In [7]: greet.__doc__
Out[7]: 'Return a friendly greeting.'

In [8]: decorated_greet.__name__
Out[8]: 'wrapper'

In [9]: decorated_greet.__doc__
None

This makes debugging and working with the Python interpreter awkward and challenging. Thankfully there’s a quick fix for this: the functools.wraps decorator included in Python’s standard library.

You can use functors.wrapsin your own decorators to copy over the lost metadata from the undecorated function to the decorator closure.

Here’s an example:

import functools

def uppercase(func):
    @functools.wraps(func)
    def wrapper():
        return func().upper()
    return wrapper

Applying functools.wraps to the wrapper closure returned by the decorator carries over the doctoring and other metadata of the input function:

greet.__name__
'greet'

greet.__doc__
'Return a friendly greeting.'

As a best practice, I’d recommended that you use functools.wraps in all of the decorators you write yourself. It doesn’t take much time and it will save you (and others) debugging headaches down the road.

Oh, and congratulations–you’ve made it all the way to the end of this complicated chapter and learned a whole lot about decorators in Python. Great job!

相关文章
|
17天前
|
监控 Python
深入理解Python中的装饰器(Decorators)
深入理解Python中的装饰器(Decorators)
|
2月前
|
Go C++ Python
Python Tricks: String Conversion(Every Class Needs a ___repr__)
Python Tricks: String Conversion(Every Class Needs a ___repr__)
|
2月前
|
前端开发 Python
Python Tricks-- Abstract Base Classes Keep Inheritance in Check
Python Tricks-- Abstract Base Classes Keep Inheritance in Check
|
2月前
|
C++ Python
Python Tricks--- Object Comparisons:“is” vs “==”
Python Tricks--- Object Comparisons:“is” vs “==”
|
2月前
|
Python
Python Tricks: Nothing to Return Here
Python Tricks: Nothing to Return Here
|
2月前
|
C# Python
Python Tricks : Function Argument Unpacking
Python Tricks : Function Argument Unpacking
|
2月前
|
Linux Go Python
Python Tricks :The Power Of Decorators
Python Tricks :The Power Of Decorators
|
2月前
|
API Python
Python Tricks : Fun With args and kwargs
Python Tricks : Fun With args and kwargs
|
7天前
|
存储 数据挖掘 开发者
Python编程入门:从零到英雄
在这篇文章中,我们将一起踏上Python编程的奇幻之旅。无论你是编程新手,还是希望拓展技能的开发者,本教程都将为你提供一条清晰的道路,引导你从基础语法走向实际应用。通过精心设计的代码示例和练习,你将学会如何用Python解决实际问题,并准备好迎接更复杂的编程挑战。让我们一起探索这个强大的语言,开启你的编程生涯吧!
|
13天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的自我修养:从Python编程入门到深度学习实践
【10月更文挑战第39天】本文旨在为初学者提供一条清晰的道路,从Python基础语法的掌握到深度学习领域的探索。我们将通过简明扼要的语言和实际代码示例,引导读者逐步构建起对人工智能技术的理解和应用能力。文章不仅涵盖Python编程的基础,还将深入探讨深度学习的核心概念、工具和实战技巧,帮助读者在AI的浪潮中找到自己的位置。
下一篇
无影云桌面