Skip to content

Instantly share code, notes, and snippets.

@maxfischer2781
Last active August 30, 2021 11:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxfischer2781/5c8660f76a8136aee076a75c48187624 to your computer and use it in GitHub Desktop.
Save maxfischer2781/5c8660f76a8136aee076a75c48187624 to your computer and use it in GitHub Desktop.
Helper that allows using the same decorator for both functions and methods
"""
Basic "Decoscriptor" example
"""
from decoscriptor import anydeco
@anydeco
def art(fun, *args, **kwargs):
print("Big Whoop and a bottle of", args, kwargs)
print("Fun is set to", getattr(fun, "__self__", "<unbound>"))
return fun(*args, **kwargs)
class Foo:
@art
def decome(self, *args, **kwargs):
print("decome:", args, kwargs)
@art
def decofu(*args, **kwargs):
print("decofu:", args, kwargs)
print(" ### Test Method ### ")
Foo().decome(1, 2, three=4)
print(" ### Test Function ### ")
decofu(1, 2, three=4)
"""
Basic "Decoscriptor" sketch that allows using the same decorator for functions and methods
"""
from functools import partial
class Decoscriptor:
"""
Helper to treat decoration of functions and methods equivalently
This class expresses that a ``call`` is decorated by ``deco``.
When called, ``deco`` is passed ``call`` and all arguments.
When used a method on an object, the ``self`` parameter is
automatically bound to ``call`` and does not appear as a positional
parameter to ``deco``. If the ``self`` parameter is desired
in the decorator, it can be extracted as ``call.__self__``.
"""
def __init__(self, deco, call):
self.deco = deco
self.call = call
def __call__(self, *args, **kwargs):
return self.deco(self.call, *args, **kwargs)
def __get__(self, instance, owner):
# TODO: Handle @classmethod and @staticmethod targets
if instance is None:
return self
return partial(self.deco, self.call.__get__(instance, owner))
def anydeco(deco):
"""Mark a decorator as handling both methods and functions equally"""
return partial(Decoscriptor, deco)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment