Pregunta

Quiero ser capaz de tener una cadena creada dinámicamente, por ejemplo "la paloma" y determinar en tiempo de ejecución si Google App Engine tiene una clase de modelo se define en este proyecto llamado "paloma". Si "la paloma" es el nombre de una clase del modelo loro, me gustaría a continuación, obtener una referencia a la clase de la paloma de modo definido.

Además, no quiero usar eval en absoluto, ya que la cadena dinámica "paloma" en este caso, viene de fuera.

¿Fue útil?

Solución

Hay dos maneras bastante fácil de hacer esto sin depender de los detalles internos:

Utilice la API google.appengine.api.datastore, así:

from google.appengine.api import datastore

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

La otra opción es utilizar la clase 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!"

El último tiene la ventaja de que se puede utilizar para generar GetEntityClass una clase Expando para cualquier tipo de entidad, e interactuar con él de la misma manera que lo haría una clase normal.

Otros consejos

Usted podría intentar, aunque probablemente muy, muy mala práctica:

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

Además, para hacer más seguro que, usted podría dar eval un hash locales: eval(nm+'()', {'Pigeon':pigeon})

No estoy seguro de si eso fuera a trabajar, y que sin duda tiene un problema: si hay una función llamada el valor de nm, sería volver que:

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

Editar : Otra forma de hacerlo es posiblemente (no probado), si se conoce el módulo:
(Lo siento, se me olvida que no es obj.hasattr, su hasattr (obj)!)

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

EDIT 2 : Sí, funciona! Woo!

En realidad, mirando a través del código fuente y interweb, encontré un método indocumentado que parece ajustarse a la ley.

from google.appengine.ext import db

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

klass = db.class_for_kind(key)

Este método lanzará una excepción descriptiva si la clase no existe, por lo que probablemente debería cogerlo si la cadena clave viene desde el exterior.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top