【问题标题】:Python Decorator also for undefined attributesPython 装饰器也用于未定义的属性
【发布时间】:2013-01-15 08:15:21
【问题描述】:

我想为用户创建一个模型类。用户的数据存储在基于文档的数据库中,如 couchdb 或 mongodb。 User 类应该有一个装饰器,并且 db 中的字段可以通过不存在的类属性访问。例如

@DocumentDB()
class User(object):
    def doSomething(self):
        pass
    def doSomethingElse(self):
        pass

u = User('thisIsAUniqUserId')
print u.emailAddress
print u.lastName

我玩过 python 装饰器。操作现有函数并不是一件大事,但我如何才能捕捉到对不存在的 getter/setter 的调用,以通过对象实例创建对 db 值的透明访问?

【问题讨论】:

  • 不确定我是否正确理解了您的问题(主要是装饰器部分),但我认为这就是您可能正在寻找的 - docs.python.org/2/reference/…

标签: python properties model couchdb decorator


【解决方案1】:

你需要实现__getattr__(self, name)method

【讨论】:

    【解决方案2】:

    对对象属性的访问由getattr/setattr/delattr/getattribute mechanism 控制。

    【讨论】:

      【解决方案3】:

      Django 使用metaclasses to dynamically create models。虽然您的要求略有不同,但同样的技术也可以工作(可能比装饰器更好)。

      你可以read more about Python metaclasses on Stackoverflow

      【讨论】:

      • 这是一个有趣的话题!也不知道...我不确定这是否适合我的需求。 Django 不直接支持基于文档的数据库。如果您最初知道数据库中的哪些字段可用,则此技术效果很好......在我的情况下,每个文档都可能略有不同,并且由于速度提高,我认为这个“代理装饰器”想法可能是一个更好的解决方案。我可能错了?
      • 不,我认为你是对的。在我发布答案后,我意识到 couchdb/mongodb 比 SQL 数据库更灵活(结构更少)。因此@Ber 的答案可能是最好的,我刚刚投了赞成票。祝你好运。
      【解决方案4】:

      我想我根据您的建议找到了解决方案:

      def DocumentDB(object):
          class TransparentAttribute:
              def __init__(self, *args, **kargs):                 
                  self.wrapped = object(*args, **kargs)
              def __getattr__(self, attrname):
                  return "Any Value"
          return TransparentAttribute
      
      @DocumentDB
      class User(object):
          def doSomething(self):
              pass
          def doSomethingElse(self):
              pass
      
      u = User()
      print u.emailAddress
      print u.lastName
      

      它有效,但它是最 Python 的方式吗?

      【讨论】:

      • 使用 DocumentDB 得到的是一个包装类。所以“TransparentAttribute”是用词不当。属性是您在 python 对象上查找的东西(无论是类还是其实例)。习惯上来说,查找未显式定义的属性是违反“显式优于隐式”的口头禅。
      • 我认为您可以将 __getattr__() 方法添加到您的 User() 类中。我不太明白包装类的必要性。
      猜你喜欢
      • 1970-01-01
      • 2018-07-22
      • 2018-01-31
      • 2016-09-11
      • 2012-06-02
      • 1970-01-01
      • 2018-07-20
      • 2018-10-25
      • 1970-01-01
      相关资源
      最近更新 更多