Recently, I was trying to store and read information from files in Python, and came across a slight problem: I wanted to read type information from text files. Type casting from string to int or to float is quite efficient, but type casting from string to type seems to be another problem. Naturally, I tried something like this:
var_type = type('int')
However, type
isn't used as a cast but as a mechanism to find the type of the variable, which is actually str
here.
I found a way to do it with:
var_type = eval('int')
But I generally try to avoid functions/statements like eval
or exec
where I can. So my question is the following: Is there another pythonic (and more specific) way to cast a string to a type?
LexicalCast provides a cast operator, boost::lexical_cast , that can convert numbers from strings to numeric types like int or double and vice versa. boost::lexical_cast is an alternative to functions like std::stoi() , std::stod() , and std::to_string() , which were added to the standard library in C++11.
One effective way to convert a string object into a numeral int is to use the stoi() function. This method is commonly used for newer versions of C++, with is being introduced with C++11. It takes as input a string value and returns as output the integer version of it.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With