¿Cómo puedo determinar dinámicamente si una clase de modelo existe en Google App Engine?
-
09-09-2019 - |
Pregunta
Quiero ser capaz de tener una cadena creada dinámicamente, por ejemplo "la paloma" y determinar en tiempo de ejecución si Google App Engine tiene una clase de modelo se define en este proyecto llamado "paloma". Si "la paloma" es el nombre de una clase del modelo loro, me gustaría a continuación, obtener una referencia a la clase de la paloma de modo definido.
Además, no quiero usar eval en absoluto, ya que la cadena dinámica "paloma" en este caso, viene de fuera.
Solución
Hay dos maneras bastante fácil de hacer esto sin depender de los detalles internos:
Utilice la API google.appengine.api.datastore, así:
from google.appengine.api import datastore
q = datastore.Query('EntityType')
if q.get(1):
print "EntityType exists!"
La otra opción es utilizar la clase db.Expando:
def GetEntityClass(entity_type):
class Entity(db.Expando):
@classmethod
def kind(cls):
return entity_type
return Entity
cls = GetEntityClass('EntityType')
if cls.all().get():
print "EntityType exists!"
El último tiene la ventaja de que se puede utilizar para generar GetEntityClass una clase Expando para cualquier tipo de entidad, e interactuar con él de la misma manera que lo haría una clase normal.
Otros consejos
Usted podría intentar, aunque probablemente muy, muy mala práctica:
def get_class_instance(nm) :
try :
return eval(nm+'()')
except :
return None
Además, para hacer más seguro que, usted podría dar eval un hash locales: eval(nm+'()', {'Pigeon':pigeon})
No estoy seguro de si eso fuera a trabajar, y que sin duda tiene un problema: si hay una función llamada el valor de nm
, sería volver que:
def Pigeon() :
return "Pigeon"
print(get_class_instance('Pigeon')) # >> 'Pigeon'
Editar : Otra forma de hacerlo es posiblemente (no probado), si se conoce el módulo:
(Lo siento, se me olvida que no es obj.hasattr, su hasattr (obj)!)
import models as m
def get_class_instance(nm) :
if hasattr(m, nm) :
return getattr(m, nm)()
else : return None
EDIT 2 : Sí, funciona! Woo!
En realidad, mirando a través del código fuente y interweb, encontré un método indocumentado que parece ajustarse a la ley.
from google.appengine.ext import db
key = "ModelObject" #This is a dynamically generated string
klass = db.class_for_kind(key)
Este método lanzará una excepción descriptiva si la clase no existe, por lo que probablemente debería cogerlo si la cadena clave viene desde el exterior.