【问题标题】:How do I dynamically determine if a Model class exist in Google App Engine?如何动态确定 Google App Engine 中是否存在 Model 类?
【发布时间】:2009-04-09 21:28:14
【问题描述】:

我希望能够获取一个动态创建的字符串,例如“Pigeon”,并在运行时确定 Google App Engine 是否在此项目中定义了一个名为“Pigeon”的模型类。如果“Pigeon”是现有模型类的名称,那么我想获得对如此定义的 Pigeon 类的引用。

另外,我根本不想使用 eval,因为在这种情况下,动态字符串“Pigeon”来自外部。

【问题讨论】:

    标签: google-app-engine model google-cloud-datastore


    【解决方案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
    

    编辑 2:是的,它确实有效!哇!

    【讨论】:

    • 是的,我也应该指定,我根本不想使用 eval,因为“Pigeon”可能来自外部。
    • 肯定的。 (愚蠢的评论最小长度 - 我会说“好的”。):D
    • 这里完全不需要eval。
    • 是。我第一次写这篇文章的时候忘记了第二种方式,把它留在那里留给后人。
    【解决方案2】:

    实际上,通过查看源代码和互联网,我发现了一个似乎符合要求的未记录方法。

    from google.appengine.ext import db
    
    key = "ModelObject" #This is a dynamically generated string
    
    klass = db.class_for_kind(key)
    

    如果类不存在,此方法将抛出描述性异常,因此如果键字符串来自外部,您可能应该捕获它。

    【讨论】:

      【解决方案3】:

      有两种相当简单的方法可以在不依赖内部细节的情况下做到这一点:

      使用 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!"
      

      后者的优点是您可以使用 GetEntityClass 为任何实体类型生成 Expando 类,并以与普通类相同的方式与之交互。

      【讨论】:

        猜你喜欢
        • 2011-07-29
        • 2011-05-08
        • 2017-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多