Lexical cast from string to type
I like using locate
, which works on built-in types:
>>> from pydoc import locate>>> locate('int')<type 'int'>>>> t = locate('int')>>> t('1')1
...as well as anything it can find in the path:
>>> locate('datetime.date')<type 'datetime.date'>>>> d = locate('datetime.date')>>> d(2015, 4, 23)datetime.date(2015, 4, 23)
...including your custom types:
>>> locate('mypackage.model.base.BaseModel')<class 'mypackage.model.base.BaseModel'>>>> m = locate('mypackage.model.base.BaseModel')>>> m()<mypackage.model.base.BaseModel object at 0x1099f6c10>
You're a bit confused on what you're trying to do. Types, also known as classes, are objects, like everything else in python. When you write int
in your programs, you're referencing a global variable called int
which happens to be a class. What you're trying to do is not "cast string to type", it's accessing builtin variables by name.
Once you understand that, the solution is easy to see:
def get_builtin(name): return getattr(__builtins__, name)
If you really wanted to turn a type name into a type object, here's how you'd do it. I use deque
to do a breadth-first tree traversal without recursion.
def gettype(name): from collections import deque # q is short for "queue", here q = deque([object]) while q: t = q.popleft() if t.__name__ == name: return t else: print 'not', t try: # Keep looking! q.extend(t.__subclasses__()) except TypeError: # type.__subclasses__ needs an argument, for whatever reason. if t is type: continue else: raise else: raise ValueError('No such type: %r' % name)