Dada una cadena como entrada del usuario a una función de Python, me gustaría obtener un objeto de clase si hay una clase con ese nombre en el espacio de nombres actualmente definido. Esencialmente, quiero la implementación de una función que produzca este tipo de resultado:
class Foo:
pass
str_to_class("Foo")
==> <class __main__.Foo at 0x69ba0>
¿Es esto posible?
Respuestas:
Esto parece más simple.
fuente
Esto podría funcionar:
fuente
def str_to_class(str): return vars()[str]
?Podrías hacer algo como:
fuente
globals()
... otra cosa que debería evitarseglobals()
podría decirse que es mucho menos malo queeval
, y en realidad no es peor quesys.modules[__name__]
AFAIK.Quieres la clase
Baz
, que vive en el módulofoo.bar
. Con Python 2.7, desea usarimportlib.import_module()
, ya que esto hará que la transición a Python 3 sea más fácil:Con Python <2.7:
Utilizar:
fuente
Esto maneja con precisión las clases de estilo antiguo y nuevo.
fuente
He visto cómo django maneja esto
django.utils.module_loading tiene esto
Puedes usarlo como
import_string("module_path.to.all.the.way.to.your_class")
fuente
Sí, usted puede hacer esto. Suponiendo que sus clases existan en el espacio de nombres global, algo como esto lo hará:
fuente
En términos de ejecución de código arbitrario, o nombres de usuario no deseados, podría tener una lista de nombres de función / clase aceptables, y si la entrada coincide con uno en la lista, se evalúa.
PD: Lo sé ... un poco tarde ... pero es para cualquiera que se encuentre con esto en el futuro.
fuente
Usar importlib funcionó mejor para mí.
Esto utiliza la notación de puntos de cadena para el módulo de Python que desea importar.
fuente
Si realmente desea recuperar las clases que realiza con una cadena, debe almacenarlas (o redactarlas correctamente, hacer referencia ) en un diccionario. Después de todo, eso también permitirá nombrar sus clases en un nivel superior y evitar exponer clases no deseadas.
Ejemplo, de un juego en el que las clases de actores se definen en Python y desea evitar que el usuario ingrese a otras clases generales.
Otro enfoque (como en el ejemplo a continuación) sería hacer una clase completamente nueva, que contenga lo
dict
anterior. Esto sería:Ejemplo:
Esto me devuelve:
Otro experimento divertido que hacer con ellos es agregar un método que conserve el encurtido
ClassHolder
para que nunca pierdas todas las clases que hiciste: ^)fuente