Michael
Michael

Reputation: 8758

staticmethod: get the class name?

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...

Upvotes: 2

Views: 3216

Answers (2)

gnr
gnr

Reputation: 2414

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.

Upvotes: 0

Jon Clements
Jon Clements

Reputation: 142106

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__

Upvotes: 1

Related Questions