26

So i have a set of classes and a string with one of the class names. How do I instantiate a class based on that string?

class foo:
  def __init__(self, left, right):
     self.left = left
     self.right = right

str = "foo"
x = Init(str, A, B)

I want x to be an instantiation of class foo.

klynch
  • 1,076
  • 2
  • 9
  • 15
  • 2
    Duplicate. http://stackoverflow.com/questions/734970/python-reference-to-a-class-from-a-string, http://stackoverflow.com/questions/1176136/convert-string-to-python-class-object, http://stackoverflow.com/questions/553784/can-you-use-a-string-to-instantiate-a-class-in-python, etc. – S.Lott Feb 09 '10 at 11:17

6 Answers6

31

In your case you can use something like:

get_class = lambda x: globals()[x]
c = get_class("foo")

And it's even easier to get the class from the module:

import somemodule
getattr(somemodule, "SomeClass")
SkunkSpinner
  • 11,429
  • 7
  • 40
  • 53
Radagast
  • 5,798
  • 3
  • 22
  • 18
20

If you know the namespace involved, you can use it directly -- for example, if all classes are in module zap, the dictionary vars(zap) is that namespace; if they're all in the current module, globals() is probably the handiest way to get that dictionary.

If the classes are not all in the same namespace, then building an "artificial" namespace (a dedicated dict with class names as keys and class objects as values), as @Ignacio suggests, is probably the simplest approach.

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
8
classdict = {'foo': foo}

x = classdict['foo'](A, B)
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
6
classname = "Foo"
foo = vars()[classname](Bar, 0, 4)

Or perhaps

def mkinst(cls, *args, **kwargs):
    try:
        return globals()[cls](*args, **kwargs)
    except:
        raise NameError("Class %s is not defined" % cls)

x = mkinst("Foo", bar, 0, 4, disc="bust")
y = mkinst("Bar", foo, batman="robin")

Miscellaneous notes on the snippet:

*args and **kwargs are special parameters in Python, they mean «an array of non-keyword args» and «a dict of keyword args» accordingly.

PEP-8 (official Python style guide) recommends using cls for class variables.

vars() returns a dict of variables defined in the local scope.

globals() returns a dict of variables currently present in the environment outside of local scope.

Mischa Arefiev
  • 5,227
  • 4
  • 26
  • 34
2

try this

cls = __import__('cls_name')

and this - http://effbot.org/zone/import-confusion.htm maybe helpful

Tom van der Woerdt
  • 29,532
  • 7
  • 72
  • 105
roma
  • 31
  • 1
0

You might consider usage of metaclass as well:

Cls = type('foo', (), foo.__dict__)
x = Cls(A, B)

Yet it creates another similar class.

Aliaksei Kuzmin
  • 589
  • 3
  • 10