Comment puis-je déterminer dynamiquement si existe une classe de modèle dans Google App Engine?
-
09-09-2019 - |
Question
Je veux être en mesure de prendre une chaîne dynamique créée, dites « Pigeon » et de déterminer à l'exécution si Google App Engine est une classe de modèle défini dans ce projet nommé « Pigeon ». Si « Pigeon » est le nom d'une classe de modèle existant, je voudrais alors obtenir une référence à la classe Pigeon ainsi définie.
En outre, je ne veux pas utiliser eval du tout, étant donné que la chaîne dynamique dans ce cas « Pigeon », vient de l'extérieur.
La solution
Il y a deux façons assez facile de faire cela sans compter sur les détails internes:
Utilisez l'API google.appengine.api.datastore, comme suit:
from google.appengine.api import datastore
q = datastore.Query('EntityType')
if q.get(1):
print "EntityType exists!"
L'autre option consiste à utiliser la classe 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!"
Ce dernier a l'avantage que vous pouvez utiliser GetEntityClass pour générer une classe Expando pour tout type d'entité, et d'interagir avec elle de la même façon que vous le feriez pour une classe normale.
Autres conseils
Vous pouvez essayer, bien que la pratique probablement très, très mauvais:
def get_class_instance(nm) :
try :
return eval(nm+'()')
except :
return None
En outre, pour faire ce plus sûr, vous pouvez donner eval un hachage de la population locale: eval(nm+'()', {'Pigeon':pigeon})
Je ne sais pas si cela fonctionne, et il a certainement un problème: s'il y a une fonction appelée la valeur de nm
, il retournerait que:
def Pigeon() :
return "Pigeon"
print(get_class_instance('Pigeon')) # >> 'Pigeon'
EDIT : Une autre façon de le faire est peut-être (non testé), si vous connaissez le module:
(Désolé, je continue à oublier qu'il est obj.hasattr pas, son hasattr (obj)!)
import models as m
def get_class_instance(nm) :
if hasattr(m, nm) :
return getattr(m, nm)()
else : return None
EDIT 2 : Oui, ça marche! Woo!
En fait, en regardant à travers le code source et interweb, j'ai trouvé une méthode non documentée qui semble correspondre à la facture.
from google.appengine.ext import db
key = "ModelObject" #This is a dynamically generated string
klass = db.class_for_kind(key)
Cette méthode renvoie une exception descriptive si la classe n'existe pas, alors vous devriez probablement attraper si la chaîne clé vient de l'extérieur.