TL;DR How do I find out whether a function was defined using @classmethod
or something with the same effect?
My problem
For implementing a class decorator I would like to check if a method takes the class as its first argument, for example as achieved via
@classmethod
def function(cls, ...):
I found a solution to check for @staticmethod
via the types
module (isinstance(foo, types.UnboundMethodType)
is False
if the foo
is static, see here), but did not find anything on how to do so for @classmethod
Context
What I am trying to do is something along the lines of
def class_decorator(cls):
for member in cls.__dict__:
if (isclassmethod(getattr(cls, member))):
# do something with the method
setattr(cls, member, modified_method)
return cls
and I do not know how to implement what I called isclassmethod
in this example
You should use inspect.ismethod. It works because classmethod binds the function to the class object. See the following code:
This works for me:
It basically tests if
method.__self__
exists and is a class, as in Martijn's answer, but does not require access to the class itself.None of the answers address the problem of identifying whether a method is decorated with class method from an instance of the class. Following code explores the class dict of an instance to distinguish between classmethod from other methods.
This will work for both Python 2 and 3.
For Python 2, you need to test both if the object is a method, and if
__self__
points to the class (for regular methods it'll beNone
when retrieved from the class):In Python 3, regular methods show up as functions (unbound methods have been done away with).
Combine this with
inspect.ismethod()
for a fail-safe method to detect a class method in both Python 2 and 3:The
method.__self__
attribute was added in Python 2.6 to be consistent with Python 3. In Python 2.6 and 2.7 it is an alias ofmethod.im_self
.