0

Similar to How to distinguish an instance method, a class method, a static method or a function in Python 3?, I would like to determine whether a given method is a class method or a static method.

In that answer it is described how to print the type in order to determine this. For example,

class Resource(object):
    @classmethod
    def parse_class(cls, string):
        pass

    @staticmethod
    def parse_static(string):
        pass

# I would like to turn these print statements into Booleans
print type(Resource.__dict__['parse_class'])
print type(Resource.__dict__['parse_static'])

prints the output

<type 'classmethod'>
<type 'staticmethod'>

I would like to take this one step further, however, and write a Boolean expression for whether a method is a class or static method.

Any ideas how to go about this? (I've had a look at the types module but none of the types seem like classmethod or staticmethod).

Community
  • 1
  • 1
Kurt Peek
  • 52,165
  • 91
  • 301
  • 526
  • Maybe I'm misunderstanding you, but do you simply want to assign the type of a static method to a variable in order to compare your methods to it? `type(staticmethod(None))` – L3viathan Mar 22 '17 at 18:44

4 Answers4

1

The types are simply classmethod and staticmethod, so if you want to perform type or isinstance checks, classmethod and staticmethod are the types to use.

user2357112
  • 260,549
  • 28
  • 431
  • 505
1

The inspect module seems to give the desired result:

import inspect

inspect.ismethod(Resource.parse_class)
inspect.ismethod(Resource.parse_static)

The first returns True, while the latter returns False.

Or using types:

import types

isinstance(Resource.parse_class, MethodType)
isinstance(Resource.parse_static, MethodType)
mdh
  • 5,355
  • 5
  • 26
  • 33
  • Why does it only *seem* to give the desired result? – wwii Mar 22 '17 at 18:53
  • That's probably not doing what you think it is. The descriptor protocol resolves `Resource.parse_static` to the actual `parse_static` function defined in the class body, while `Resource.parse_class` resolves to a bound method object. It's kind of a fluke that things work out this way, and it's not a very clear way to accomplish the desired objective. – user2357112 Mar 22 '17 at 18:55
  • @user2358112: `type(Resource.parse_class)` -> `instancemethod` vs `type(Resource.parse_static)` -> `function` – mdh Mar 22 '17 at 18:59
  • If you want the second Boolean to also be `True`, you should do `type(Resource.parse_static) == types.FunctionType`. – Kurt Peek Mar 23 '17 at 10:23
1

You want:

isinstance(vars(Resource)['parse_class'], classmethod)
isinstance(vars(Resource)['parse_static'], staticmethod)

And using vars(my_object) is just a cleaner way of accessing my_object.__dict__

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
1

The keywords staticmethod and classmethod represent the homonymous types:

In [1]: staticmethod.__class__
Out[1]: type

In [2]: type(staticmethod)
Out[2]: type

In [3]: classmethod.__class__
Out[3]: type

In [4]: type(classmethod)
Out[4]: type

So that means you can use them to compare the statement you are printing in your example:

In [5]: class Resource(object):
   ...:     @classmethod
   ...:     def parse_class(cls, string):
   ...:         pass
   ...: 
   ...:     @staticmethod
   ...:     def parse_static(string):
   ...:         pass
   ...:     

 In [6]: print type(Resource.__dict__['parse_class']) == classmethod
 True

 In [7]: print type(Resource.__dict__['parse_static']) == staticmethod
 True

Cheers!

Pericolo
  • 537
  • 4
  • 4