tags:

views:

775

answers:

5

Given a string as user input to a python function, I'd like to get a class object out of it if there's a class with that name in the currently defined namespace. Essentially, I want the implementation for a function which will produce this kind of result:

class Foo:
    pass

str_to_class("Foo")
==> <class __main__.Foo at 0x69ba0>

Is this possible?

A: 

You could do something like:

globals()[class_name]()

but that could easily blow up if the class's constructor (ie: the __init__ method) requires additional parameters.

Laurence Gonsalves
+3  A: 

This could work:

import sys

def str_to_class(str):
    return getattr(sys.modules[__name__], str)
sixthgear
What will happen if the class does not exist?
Selinap
It will only work for the class defined in the current module
luc
A: 

Yes, you can do this. Assuming your classes exist in the global namespace, something like this will do it:

import types

class Foo:
    pass

def str_to_class(s):
    if s in globals() and isinstance(globals()[s], types.ClassType):
            return globals()[s]
    return None

str_to_class('Foo')

==> <class __main__.Foo at 0x340808cc>
ollyc
In Python 3, there is no more ClassType.
Selinap
Use isinstance(x, type).
Glenn Maynard
A: 
import sys
import types

def str_to_class(field):
    try:
        identifier = getattr(sys.modules[__name__], field)
    except AttributeError:
        raise NameError("%s doesn't exist." % field)
    if isinstance(identifier, (types.ClassType, types.TypeType)):
        return identifier
    raise TypeError("%s is not a class." % field)

This accurately handles both old-style and new-style classes.

Evan Fosmark
You don't need types.TypeType; it's just an alias for the builtin "type".
Glenn Maynard
Yeah I know, but I feel it's just clearer to read.I guess it just boils down to preference, though.
Evan Fosmark
A: 

This seems simplest.

>>> class Foo(object):
...     pass
... 
>>> eval("Foo")
<class '__main__.Foo'>
S.Lott