statement - python string to int
Elenco léxico de la cuerda al tipo (4)
Recientemente, estaba tratando de almacenar y leer información de archivos en Python, y encontré un pequeño problema: quería leer información de tipo de archivos de texto. La conversión de tipos de cadena a int o flotar es bastante eficiente, pero la conversión de tipos de cadena a tipo parece ser otro problema. Naturalmente, probé algo como esto:
var_type = type(''int'')
Sin embargo, el type
no se usa como una conversión, sino como un mecanismo para encontrar el tipo de la variable, que en realidad es str
aquí.
Encontré una manera de hacerlo con:
var_type = eval(''int'')
Pero generalmente trato de evitar funciones / declaraciones como eval
o exec
donde pueda. Así que mi pregunta es la siguiente: ¿Existe otra forma pitónica (y más específica) de convertir una cadena a un tipo?
¿Por qué no usar una tabla de consulta?
known_types = {
''int'': int,
''float'': float,
''str'': str
# etc
}
var_type = known_types[''int'']
Estás un poco confundido sobre lo que estás tratando de hacer. Los tipos, también conocidos como clases, son objetos, como todo lo demás en python. Cuando escribe int
en sus programas, está haciendo referencia a una variable global llamada int
que resulta ser una clase. Lo que estás tratando de hacer no es "convertir la cadena al tipo", está accediendo a las variables incorporadas por nombre.
Una vez que entiendas eso, la solución es fácil de ver:
def get_builtin(name):
return getattr(__builtins__, name)
Si realmente quisieras convertir un nombre de tipo en un objeto de tipo, así es como lo harías. Uso el deque
para hacer un recorrido de árbol sin amplitud sin recursión.
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)
Me gusta usar locate
, que funciona en tipos incorporados:
>>> from pydoc import locate
>>> locate(''int'')
<type ''int''>
>>> t = locate(''int'')
>>> t(''1'')
1
... así como todo lo que pueda encontrar en el camino:
>>> locate(''datetime.date'')
<type ''datetime.date''>
>>> d = locate(''datetime.date'')
>>> d(2015, 4, 23)
datetime.date(2015, 4, 23)
... incluyendo sus tipos personalizados:
>>> locate(''mypackage.model.base.BaseModel'')
<class ''mypackage.model.base.BaseModel''>
>>> m = locate(''mypackage.model.base.BaseModel'')
>>> m()
<mypackage.model.base.BaseModel object at 0x1099f6c10>
Quizás esto es lo que quieres, se ve solo en los tipos incorporados:
def gettype(name):
t = getattr(__builtins__, name)
if isinstance(t, type):
return t
raise ValueError(name)