Skip to content

Instantly share code, notes, and snippets.

@bartolootrit
Last active November 26, 2018 07:34
Show Gist options
  • Save bartolootrit/c35e37cad2ecf690452e11510802ddb5 to your computer and use it in GitHub Desktop.
Save bartolootrit/c35e37cad2ecf690452e11510802ddb5 to your computer and use it in GitHub Desktop.
Python decorator for static functions and instance methods
# Author: aurzenligl (https://stackoverflow.com/users/7249587/aurzenligl)
# see https://stackoverflow.com/a/48836522/704244
from functools import wraps
def _declassify(fun, args):
if len(args):
met = getattr(args[0], fun.__name__, None)
if met:
wrap = getattr(met, '__func__', None)
if getattr(wrap, 'original', None) is fun:
maybe_cls = args[0]
cls = maybe_cls if isclass(maybe_cls) else maybe_cls.__class__
return cls, args[1:]
return None, args
def decorated(fun):
desc = next((desc for desc in (staticmethod, classmethod)
if isinstance(fun, desc)), None)
if desc:
fun = fun.__func__
@wraps(fun)
def wrap(*args, **kwargs):
cls, nonselfargs = _declassify(fun, args)
clsname = cls.__name__ if cls else None
print('class: %-10s func: %-15s args: %-10s kwargs: %-10s' %
(clsname, fun.__name__, nonselfargs, kwargs))
wrap.original = fun
if desc:
wrap = desc(wrap)
return wrap
class C:
@decorated
def f(self, a, b):
print(a, b)
@staticmethod
@decorated
def g(a, b):
print(a, b)
@classmethod
@decorated
def h(cls, a, b):
print(a, b)
C().f(1, 2)
C.g(1, 2)
C.h(1, 2)
class D:
def g(self):
pass
class H:
def h(self):
pass
C.g(D(), 2)
C.g(H(), 2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment