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.

Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top