Frage

Ich möchte eine dynamisch erstellte Zeichenfolge zu übernehmen zu können, sagen: „Pigeon“ und bestimmt zur Laufzeit, ob Google App Engine eine Modellklasse hat bei diesem Projekt definierten Namen „Pigeon“. Wenn „Pigeon“ ist der Name eines existant Modellklasse würde Ich mag, um dann einen Verweis auf die Pigeon Klasse bekommen so definiert ist.

Auch ich will überhaupt nicht eval verwenden, da die dynamische Zeichenfolge „Pigeon“ in diesem Fall kommt von außen.

War es hilfreich?

Lösung

Es gibt zwei recht einfache Möglichkeiten, dies zu tun, ohne auf interne Details zu verlassen:

Mit der google.appengine.api.datastore API, etwa so:

from google.appengine.api import datastore

q = datastore.Query('EntityType')
if q.get(1):
  print "EntityType exists!"

Die andere Option ist die db.Expando Klasse verwendet wird:

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!"

Letzteres hat den Vorteil, dass Sie GetEntityClass können eine Expando-Klasse für jede Einheit Typ zu erzeugen, und mit ihm interagieren auf die gleiche Weise würde eine normale Klasse.

Andere Tipps

Sie könnten versuchen, wenn auch wahrscheinlich sehr, sehr schlechte Praxis:

def get_class_instance(nm) :
    try :
        return eval(nm+'()')
    except :
        return None

Auch zu machen, dass sicherer, Sie eval einen Einheimischen Hash geben könnte: eval(nm+'()', {'Pigeon':pigeon})

Ich bin mir nicht sicher, ob das funktionieren würde, und es hat auf jeden Fall ein Problem: wenn es eine Funktion des Wert nm genannt ist, wäre es, dass zurückgeben:

def Pigeon() :
    return "Pigeon"
print(get_class_instance('Pigeon')) # >> 'Pigeon'

Bearbeiten : Eine andere Möglichkeit, es zu tun, ist möglicherweise (nicht getestet), wenn Sie das Modul wissen:
(Sorry, ich vergesse immer wieder, es ist nicht obj.hasattr, seine hasattr (obj)!)

import models as m
def get_class_instance(nm) :
    if hasattr(m, nm) :
        return getattr(m, nm)()
    else : return None

EDIT 2 : Ja, es funktioniert! Woo!

Eigentlich Blick durch den Quellcode und interweb, fand ich eine nicht dokumentierte Methode, um die Rechnung zu passen scheint.

from google.appengine.ext import db

key = "ModelObject" #This is a dynamically generated string

klass = db.class_for_kind(key)

Diese Methode wird eine beschreibende Ausnahme auslösen, wenn die Klasse nicht vorhanden ist, so dass Sie wahrscheinlich fangen sollen, wenn die Schlüsselfolge von außen kommt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top