2009-04-09 2 views
1

Ich möchte in der Lage sein, eine dynamisch erstellte Zeichenfolge zu nehmen, sagen "Pigeon" und bestimmen zur Laufzeit, ob Google App Engine eine Model-Klasse in diesem Projekt namens "Pigeon" definiert hat. Wenn "Pigeon" der Name einer existierenden Modellklasse ist, möchte ich dann einen Verweis auf die so definierte Pigeon-Klasse erhalten.Wie ermittle ich dynamisch, ob eine Model-Klasse in Google App Engine vorhanden ist?

Auch ich möchte eval überhaupt nicht verwenden, da die dynamische Zeichenfolge "Pigeon" in diesem Fall von außen kommt.

Antwort

0

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

Verwenden Sie die 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 verwenden db.Expando Klasse:

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 die gleiche Art und Weise Du würdest eine normale Klasse bekommen.

1

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 geben könnte ein Einheimischen hash: 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 der Wert nm genannt ist, wäre es, dass zurückgeben:

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

EDIT: 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! Umwerben!

+0

Ja, ich hätte auch angeben sollen, ich möchte eval gar nicht verwenden, da "Pigeon" von draußen kommen könnte. –

+0

Affitmativ. (Blöder Kommentar min. Länge - ich hätte gerade "OK" gesagt.): D –

+0

eval ist hier völlig unnötig. –

1

Eigentlich sah ich durch den Quellcode und das Interweb eine undokumentierte Methode, die der Rechnung zu entsprechen 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 existiert, so sollten Sie es wahrscheinlich fangen, wenn die Schlüsselfolge von außen kommt.