2

Is there a way to find the name of the class a staticmethod belongs to?

class A(object):
    @staticmethod
    def my_staticmethod():
        return 'static'

    @classmethod
    def my_classmethod():
        return 'classmethod'


In [2]: A.my_staticmethod
Out[2]: <function utils.my_staticmethod>

In [3]: A.my_classmethod
Out[3]: <bound method type.my_classmethod of <class 'utils.A'>>
In [4]: A.my_classmethod.im_self.__name__
Out[4]: 'A'

For a classmethod, I can get the name of the class via A.my_classmethod.im_self.__name__ but I could not figure it out for a staticmethod.

Any idea? Thanks.


Well, actually here is what I am trying to do. I am trying to make 2 functions to "serialize/deserialize" a function/classmethod/staticmethod.

That means, someone can pass a function into the serialize function and gets a string.

a_string = serialize(A.my_classmethod)

This string can be stored in the DB for example.. Then, this string should be sufficient to resolve the function to be able to call it:

# later on...
f = deserialize(a_string)
# I can use my function
f(...)

I could make it work for a function or a classmethod but not for a staticmethod since I can't figure out the class it belongs to and use getattr...

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Michael
  • 8,357
  • 20
  • 58
  • 86
  • possible duplicate of [In python how to get name of a class inside its static method](http://stackoverflow.com/questions/4691925/in-python-how-to-get-name-of-a-class-inside-its-static-method) – BrenBarn Jul 28 '12 at 20:51
  • Basically the whole point of a staticmethod is that it has no connection to its class. If you want to know what class it's in, don't use a staticmethod. – BrenBarn Jul 28 '12 at 20:52
  • also duplicated here: http://stackoverflow.com/questions/949259/how-do-i-infer-the-class-to-which-a-staticmethod-belongs – gnr Jul 28 '12 at 20:55
  • @BrenBarn Agreed. This is like asking how to drive your car after you have taken it's wheels off. The answer is put them back on again. – Gareth Latty Jul 28 '12 at 20:56
  • You could do something gnarly with `inspect` if you wanted, but there's probably an easy solution to what you're trying to do, perhaps a simple `hasattr(A, 'my_staticmethod')` is what you're looking for? – gnr Jul 28 '12 at 20:58
  • Possible duplicate of [How to get (sub)class name from a static method in Python?](http://stackoverflow.com/questions/3596641/how-to-get-subclass-name-from-a-static-method-in-python) – Mr_and_Mrs_D Apr 27 '17 at 09:22

2 Answers2

1

Using "voodoo" you can work it out, but seriously - are you just trying to circumvent the data-model - and what is that good for? If you want a class method - use a class method. If they were meant to be interchangeable, they wouldn't be different!

And also:

@classmethod
def my_classmethod():
    return 'classmethod'

should really be:

@classmethod
def my_classmethod(cls): # assuming no args
    return cls.__name__ # instead of A.my_classmethod.im_self.__name__
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
  • Actually, I do not know what the classmethod will do, I wasn't looking for a method to return the name of the class. Look at my second post to see what I really meant. Thx. – Michael Jul 28 '12 at 21:19
  • In response to your two questions: 1) Why wasn't this your original question => I wanted to ask a simpler question by just asking about the roadblock I was going through which is to get the class name knowing a staticmethod. 2) with everyone telling you it's a bad idea, albeit do-able with black magic, you feel this is still the right way to do things? => I am using Django signals and I wanted to persist in the DB the receiver (without knowing them) connected to the signals, so I wanted to be able to serialize/deserialize the functions (even if it's a staticmethod). Hope it makes sense now. – Michael Jul 29 '12 at 07:40
0

In response to your comment about serialization/deserialization, you could change the interface:

def serialize(cls, function):
    return '{cls}.{func}'.format(cls=cls.__name__, func=function.__name__)

and you can use sys.modules[__name__].__name__ for any module-level functions.

For deserialization you might find inspect.classify_class_attrs(cls) useful.

gnr
  • 2,324
  • 1
  • 22
  • 24
  • Ok, so I conclude there is no way to access to the name of the class from a staticmethod without passing the class itself. I first wanted to have the same use case (passing just a function) whatever the function is. Well, I am going to avoid passing a staticmethod then and write in the doc that staticmethods do not work. Thanks. – Michael Jul 29 '12 at 07:45