tags:

views:

132

answers:

4

Starting with a class like this:

class FooClass(object):
    @staticmethod
    def static_method(x):
        print x

normally, I would call the static method of the class with:

FooClass.static_method('bar')

Is it possible to invoke this static method having just the class name and the method name?

class_name = 'FooClass'
method_name = 'static_method'
+1  A: 

If the class type is accessible from the current module, you can access the class in the globals() dict and the method using getattr:

class FooClass(object):
    @staticmethod
    def static_method(x):
        print x

class_name = 'FooClass'
method_name = 'static_method'

getattr(globals()[class_name], method_name)("test")
AndiDog
using globals() or locals() is an unnecessary hack
Ivo van der Wijk
@Ivo van der Wijk: So what do you propose instead?
AndiDog
@Ivo van der Wijk: Didn't see your answer. The OP's use case is obviously already a hack, so why not use the standard Python dictionaries to access the class?
AndiDog
+1  A: 

Here is a crude way:

>>> class FooClass(object):
    @staticmethod
    def static_method(x):
        print x


>>> class_name = 'FooClass'
>>> method_name = 'static_method'
>>> getattr(locals().get(class_name), method_name)("bar")
bar

Breakup:

locals().get(class_name)

First, locate the class. In this case I'm using locals() as I know that the class is available in the local dictionary. This will fail if the class is not present in the local dictionary.

Next, find the method of the class.

getattr(locals().get(class_name), method_name)

This uses getattr().

Finally, call the method.

getattr(locals().get(class_name), method_name)("bar")
Manoj Govindan
+5  A: 

You shouldn't mess with locals() as suggested in other answers. If you have your classname as a string and need to resolve it, use registry of some sort. A dictionary will work fine. E.g.

class FooClass(object):
    @staticmethod
    def static_method(x):
        print x

registry = {'FooClass':FooClass}

(I assume you will want to add many more classes to this registry)

the lookup then becomes almost trivial:

getattr(registry['FooClass'], 'static_method')("bar")
Ivo van der Wijk
+1 for the most sane option.
delnan
Agreed. `locals` and `globals` should be the last resort. +1.
Manoj Govindan
+1  A: 

you can use getattr twice. the first time on the module that contains the class and the second time on the class itself

class_name = 'Foo'
method_name = 'Bar'

cls = getattr(mod, clsname)
method = getattr(cls, method_name)
method(args)

This is not as flexible as building a registry (which you can do with a decorator) but if you are not going to do that, than this is a far better alternative than messing with the stack and stylistically, cleaner than messing with sys.modules.

Note that a module can import itself with no adverse effects. so the classes don't have to be in a different module for this to work.

aaronasterling
Your observation about how it would be better to use `getattr()` on the module object is well taken, because one will likely have it handy anyway. I tried to write my slightly earlier answer so it would work while making as few assumptions as possible.
martineau