Come posso dinamicamente determinare se una classe modello esiste in Google App Engine?
-
09-09-2019 - |
Domanda
Voglio essere in grado di prendere una stringa creata dinamicamente, dire "Piccione" e determinare in fase di esecuzione se Google App Engine ha una classe modello definito in questo progetto denominato "Piccione". Se "piccione" è il nome di una classe del modello inesistente, vorrei quindi ottenere un riferimento alla classe Pigeon così definita.
Inoltre, non voglio usare eval a tutti, dal momento che la stringa dinamica "Pigeon" in questo caso, viene da fuori.
Soluzione
Ci sono due semplici modi abbastanza per fare questo senza fare affidamento su dettagli interni:
Utilizzare l'API google.appengine.api.datastore, in questo modo:
from google.appengine.api import datastore
q = datastore.Query('EntityType')
if q.get(1):
print "EntityType exists!"
L'altra opzione è quella di utilizzare 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!"
Quest'ultimo ha il vantaggio che è possibile utilizzare GetEntityClass per generare una classe Expando per qualsiasi tipo di entità, e interagire con esso allo stesso modo si farebbe una classe normale.
Altri suggerimenti
Si potrebbe provare, anche se probabilmente molto, molto cattiva pratica:
def get_class_instance(nm) :
try :
return eval(nm+'()')
except :
return None
Inoltre, per rendere più sicuro che, si potrebbe dare eval un hash locali: eval(nm+'()', {'Pigeon':pigeon})
Non sono sicuro se questo avrebbe funzionato, e ha sicuramente un problema: se c'è una funzione chiamata il valore di nm
, che sarebbe tornato che:
def Pigeon() :
return "Pigeon"
print(get_class_instance('Pigeon')) # >> 'Pigeon'
Modifica : Un altro modo di farlo è forse (non testato), se si conosce il modulo:
(Sorry, continuo a dimenticare che non è obj.hasattr, la sua hasattr (obj)!)
import models as m
def get_class_instance(nm) :
if hasattr(m, nm) :
return getattr(m, nm)()
else : return None
Modifica 2 : Sì, funziona! Woo!
In realtà, guardando attraverso il codice sorgente e interweb, ho trovato un metodo non documentato che sembra adattarsi il disegno di legge.
from google.appengine.ext import db
key = "ModelObject" #This is a dynamically generated string
klass = db.class_for_kind(key)
Questo metodo un'eccezione descrittiva se la classe non esiste, quindi probabilmente si dovrebbe prenderlo se la stringa chiave proviene dall'esterno.