Как динамически определить, существует ли класс модели в Google App Engine?

StackOverflow https://stackoverflow.com/questions/735985

Вопрос

Я хочу иметь возможность взять динамически созданную строку, скажем «Pigeon», и определить во время выполнения, есть ли в Google App Engine определенный в этом проекте класс модели с именем «Pigeon».Если «Голубь» — это имя существующего класса модели, я хотел бы затем получить ссылку на определенный таким образом класс Pigeon.

Кроме того, я вообще не хочу использовать eval, поскольку динамическая строка «Голубь» в данном случае приходит извне.

Это было полезно?

Решение

Есть два довольно простых способа сделать это, не полагаясь на внутренние детали:

Используйте API google.appengine.api.datastore, например:

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:Да, это работает!Ву!

На самом деле, просматривая исходный код и Интернет, я нашел недокументированный метод, который, кажется, отвечает всем требованиям.

from google.appengine.ext import db

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

klass = db.class_for_kind(key)

Этот метод выдаст описательное исключение, если класс не существует, поэтому вам, вероятно, следует его перехватить, если строка ключа поступает извне.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top