Reputation: 125
I know I can use closure and inheritance to create a decorator that alter classes.
def wrapper(cls, *args, **kwargs):
class Wrapped(cls):
"""Modify your class here."""
return Wrapped
But if I need to test my new classes to know if they inherit Wrapped
or not, I can't access Wrapped
itself to do a straightforward isinstance
or issubclass
test.
On the other hand, straightforward inheritance isn't an option. I have about 10 different wrapper which can need to be added to a class. That burden the hierarchy tree way too much.
So I need a way to access the closure from the outside. Or an alternative way to build decorator.
Upvotes: 1
Views: 57
Reputation: 1121714
You could inherit from two classes, a base class and cls
:
class WrapperBase:
pass
def wrapper(cls, *args, **kwargs):
class Wrapped(cls, WrapperBase):
"""Modify your class here."""
return Wrapped
Now all instances of generated classes test True
for isinstance(obj, WrapperBase)
.
Note that WrapperBase
has no impact on finding inherited methods in the MRO; it comes dead last in any hierarchy (on Python 2, not inheriting from object
puts it dead last in the MRO, in Python 3 it'll sit between object
and whatever came before object
in the MRO of the wrapped class.
Upvotes: 1
Reputation: 229341
It sounds like you want to check whether a class has been wrapped by this particular decorator. The most efficacious method to do so may simply be to add a field to that effect, to wit:
def wrapper(cls, *args, **kwargs):
class Wrapped(cls):
"""Modify your class here."""
Wrapped._is_wrapped_by_this_wrapper = True
return Wrapped
Then you can check hasattr
and getattr
of _is_wrapped_by_this_wrapper
.
If you have multiple wrapper classes that work with each other you may be able to come up with a solution that works better together, e.g. perhaps a set
consisting of all the names of the wrappers that have been applied.
Upvotes: 2