Google App Engine に Model クラスが存在するかどうかを動的に判断するにはどうすればよいですか?
-
09-09-2019 - |
質問
動的に作成された文字列(たとえば「Pigeon」)を取得して、Google App Engine にこのプロジェクトに「Pigeon」という名前の Model クラスが定義されているかどうかを実行時に判断できるようにしたいと考えています。「Pigeon」が既存のモデル クラスの名前である場合、そのように定義された Pigeon クラスへの参照を取得したいと思います。
また、この場合の動的文字列「Pigeon」は外部から取得されるため、eval はまったく使用したくありません。
解決
内部の詳細に依存することなく、これを実行するには、2つの非常に簡単な方法があります:
、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!"
、後者は、あなたが任意のエンティティタイプについてはExpandoクラスを生成し、それをあなたが通常のクラスと同じように対話するGetEntityClassを使用することができるという利点を持っています。
他のヒント
おそらく非常に悪い習慣を試すこともできます。
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)
クラスが存在しない場合、このメソッドは、記述例外がスローされますので、キーの文字列は外から来る場合、あなたはおそらくそれをキャッチする必要があります。