1

動的に作成された文字列 (「Pigeon」など) を取得して、Google App Engine に「Pigeon」という名前のこのプロジェクトで定義されたモデル クラスがあるかどうかを実行時に判断できるようにしたいと考えています。「Pigeon」が既存のモデル クラスの名前である場合、そのように定義された Pigeon クラスへの参照を取得したいと思います。

また、この場合の動的文字列「Pigeon」は外部から取得されるため、eval はまったく使用したくありません。

4

3 に答える 3

1

実際、ソースコードとインターウェブを調べてみると、法案に適合していると思われる文書化されていない方法が見つかりました。

from google.appengine.ext import db

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

klass = db.class_for_kind(key)

このメソッドは、クラスが存在しない場合に説明的な例外をスローするため、キー文字列が外部からのものである場合は、おそらくそれをキャッチする必要があります。

于 2009-04-10T19:03:49.557 に答える
1

おそらく非常に悪い習慣ですが、試すことができます:

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

EDIT 2:はい、うまくいきます!ウー!

于 2009-04-09T21:33:46.207 に答える
0

内部の詳細に依存せずにこれを行うには、2つの非常に簡単な方法があります。

次のように、google.appengine.api.datastoreAPIを使用します。

from google.appengine.api import datastore

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

もう1つのオプションは、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クラスを生成し、通常のクラスと同じように操作できるという利点があります。

于 2009-05-03T14:15:57.370 に答える