Pergunta

Eu quero ser capaz de tomar uma corda criados dinamicamente, diga "Pigeon" e determinar em tempo de execução se o Google App Engine tem uma classe de modelo definido neste projeto chamado "Pigeon". Se "Pigeon" é o nome de uma classe de modelo foram inexistentes, eu gostaria de, em seguida, obter uma referência para a classe Pigeon assim definido.

Além disso, eu não quero usar eval em tudo, desde a corda dinâmica "Pigeon", neste caso, vem de fora.

Foi útil?

Solução

Há duas maneiras bastante fácil de fazer isso sem depender de detalhes internos:

Use o google.appengine.api.datastore API, assim:

from google.appengine.api import datastore

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

A outra opção é usar a classe 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!"

O último tem a vantagem de que você pode usar GetEntityClass para gerar uma classe Expando para qualquer tipo de entidade, e interagir com ele da mesma forma que faria uma classe normal.

Outras dicas

Você poderia tentar, embora provavelmente muito, muito má prática:

def get_class_instance(nm) :
    try :
        return eval(nm+'()')
    except :
        return None

Além disso, para tornar esse seguro, você poderia dar eval um hash locals: eval(nm+'()', {'Pigeon':pigeon})

Eu não tenho certeza se isso iria funcionar, e ele definitivamente tem um problema: se existe uma função chamada o valor de nm, retornaria que:

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

Editar : Outra maneira de fazer isso é possivelmente (não testado), se você sabe o módulo:
(Desculpe, eu continuo esquecendo que não é obj.hasattr, sua hasattr (obj)!)

import models as m
def get_class_instance(nm) :
    if hasattr(m, nm) :
        return getattr(m, nm)()
    else : return None

EDIT 2 : Sim, ela não funciona! Woo!

Na verdade, olhando através do código-fonte e interweb, eu encontrei um método não documentado que parece caber a conta.

from google.appengine.ext import db

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

klass = db.class_for_kind(key)

Este método irá lançar uma exceção descritiva se a classe não existe, então você provavelmente deve pegá-lo se a cadeia de chave vem de fora.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top