I'd like to wrap every method of a particular class in python, and I'd like to do so by editing the code of the class minimally. How should I go about this?
相关问题
- how to define constructor for Python's new Nam
- streaming md5sum of contents of a large remote tar
- How to get the background from multiple images by
- Evil ctypes hack in python
- Correctly parse PDF paragraphs with Python
An elegant way to do it is described in Michael Foord's Voidspace blog in an entry about what metaclasses are and how to use them in the section titled A Method Decorating Metaclass. Simplifying it slightly and applying it to your situation resulted in this:
In Python, function/method decorators are just function wrappers plus some syntactic sugar to make using them easy (and prettier).
Python 3 Compatibility Update
The previous code uses Python 2.x metaclass syntax which would need to be translated in order to be used in Python 3.x, however it would then no longer work in the previous version. This means it would need to use:
instead of:
If desired, it's possible to write code which is compatible both both Python 2.x and 3.x, but doing so requires using a slightly more complicated technique which dynamically creates a new base class that inherits the desired metaclass, thereby avoiding errors due to the syntax differences between the two versions of Python. This is basically what Benjamin Peterson's six module's
with_metaclass()
function does.You mean programatically set a wrapper to methods of a class?? Well, this is probably a really bad practice, but here's how you may do it:
If you have class, for example
and a wrapper
then calling
will apply
wrapper
to all methods defined in classTest
. Use with caution! Actually, don't use it at all!Using python decorators is the cleanest method of doing this, as it looks like you want to debug or at least trace the code it appears.
If extensively modifying default class behavior is the requirement, MetaClasses are the way to go. Here's an alternative approach.
If your use case is limited to just wrapping instance methods of a class, you could try overriding the
__getattribute__
magic method.Make sure to use
functools.wraps
while creating wrappers, even more so if the wrapper is meant for debugging since it provides sensible TraceBacks.