Hacker News new | ask | show | jobs
by scoutoss11235 3608 days ago
For what it's worth, the classmethod issue that concerns the author is mostly a non-issue if you apply your decorator before you wrap your function in a classmethod:

  In [1]: def my_decorator(f):
     ...:     def wrapped(*args, **kwargs):
     ...:         print("wrapping %s" % f.__name__)
     ...:         return f(*args, **kwargs)
     ...:     return wrapped
     ...:
  
  In [2]: class Foo:
     ...:     @classmethod
     ...:     @my_decorator
     ...:     def meth(cls, x, y):
     ...:         return x + y
     ...:
  
  In [3]: Foo.meth(1, 2)
  wrapping meth
  Out[3]: 3
This works because the user-defined decorator gets applied to the underlying function before it gets wrapped in a classmethod object (which doesn't supply the desired __name__ attribute).

The signature introspection issue is real, and dealing with it in full generality requires a fair amount of work, especially if you want to be compatible with python 2 and python 3.

1 comments

In general, classmethod and staticmethod and property should almost always be the last decorator applied if you decorate a method multiple times in Python. This is because, unlike most decorators, classmethod/staticmethod/property don't return functions; they return objects that implement Python's descriptor protocol (https://docs.python.org/3/howto/descriptor.html) slightly differently than how it's implemented by functions. (The core of how methods work in Python is based on the fact that functions are just descriptors (https://docs.python.org/3/howto/descriptor.html#functions-an...).