我希望能夠採用動態創建的字符串,比如說「Pigeon」,並在運行時確定Google App Engine是否在此項目中定義了一個名爲「Pigeon」的Model類。如果「Pigeon」是一個existant模型類的名稱,那麼我想再引用這樣定義的Pigeon類。如何動態確定Google App Engine中是否存在Model類?
而且,我不想使用eval可言,因爲動態字符串「鴿子」在這種情況下,來自外部。
我希望能夠採用動態創建的字符串,比如說「Pigeon」,並在運行時確定Google App Engine是否在此項目中定義了一個名爲「Pigeon」的Model類。如果「Pigeon」是一個existant模型類的名稱,那麼我想再引用這樣定義的Pigeon類。如何動態確定Google App Engine中是否存在Model類?
而且,我不想使用eval可言,因爲動態字符串「鴿子」在這種情況下,來自外部。
有兩個相當簡單的方法來做到這一點,而不依賴於內部細節:
使用google.appengine.api.datastore API,就像這樣:
from google.appengine.api import datastore
q = datastore.Query('EntityType')
if q.get(1):
print "EntityType exists!"
另一種選擇是使用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!"
後者的優點是可以使用GetEntityClass產生任何實體類型在Expando類,並用同樣的方式進行交互的優勢你會成爲一個普通的班級。
你可以嘗試,雖然可能非常,非常糟糕的做法:
def get_class_instance(nm) :
try :
return eval(nm+'()')
except :
return None
此外,爲了使更安全的,你可以給一個EVAL當地人哈希:eval(nm+'()', {'Pigeon':pigeon})
我不知道如果這會工作,它肯定有一些問題:如果有一個叫nm
價值函數,它會返回:
def Pigeon() :
return "Pigeon"
print(get_class_instance('Pigeon')) # >> 'Pigeon'
編輯:這樣做的另一種方式可能是(未經測試),如果你知道模塊:
(對不起,我一直忘了這不是obj.hasattr,其hasattr(OBJ)!)
import models as m
def get_class_instance(nm) :
if hasattr(m, nm) :
return getattr(m, nm)()
else : return None
編輯2:是的,它確實有效!嗚!
實際上,通過源代碼和interweb看,我發現,似乎符合該法案一無證方法。
from google.appengine.ext import db
key = "ModelObject" #This is a dynamically generated string
klass = db.class_for_kind(key)
此方法將拋出一個描述性的異常,如果該類不存在,所以你可能要趕上它,如果密鑰字符串來自外部。
是的,我也應該指出,我不想使用eval,因爲「鴿子」可能來自外部。 – 2009-04-09 21:37:42