Python字典的子类化

3
我正在使用ElasticSearch在我的Python应用程序中,并希望能够创建一个可重复使用的字典对象来表示查询。JSON结构在这里描述:http://pulkitsinghal.blogspot.co.uk/2012/02/how-to-use-elasticsearch-query-dsl.html,我正在使用PyES查询搜索服务器。使用PyES,我们可以传递一个字典对象,在发送到服务器之前进行json化。我想创建一个常见查询的库,其中只有实际查询术语会更改,因此我认为我会子类化字典,以便我可以通过构造函数传递查询术语,例如,当字典被json化时,我将得到像这样的结果:
{
  "fields": [
    "name",
    "shortDescription",
    "longDescription"
  ],
  "query": {
    "query_string": {
      "fields": [
        "name"
      ],
      "query": query_term,
      "use_dis_max": true
    }
  }
}

我该怎么做?只有实例成员通过__dict__返回,这是真的吗?如果是这样,我是否需要在构造函数中设置这个数据结构?这是最好的方法还是应该创建一个不扩展字典的类,并创建一个to_dict()方法,以正确的结构返回字典?
回答:
这似乎很好用,欢迎提出更多“Pythonic”的建议!(是的,我知道没有文档字符串)
class StandardQuery(object):

      search_fields = ['meta_keywords', 'meta_description', \
                       'fields.title.value', 'slug']
      return_fields = ['slug', 'fields.title.value']

      def __init__(self, query):

          self.query = query

      def to_dict(self):

          output = dict()

          output['fields'] = self.search_fields
          output['query'] = {'query_string': {'fields': self.return_fields, \
                                              'query': self.query, 'use_dis_max': True}}

          return output

你的 StandardQuery 类看起来很好。如果你想在单个实例中修改 search_fieldsreturn_fields,请确保重新绑定而不是突变列表:类属性在这里完全适用,但当它们是可变的时候必须小心。 - Duncan
1个回答

4

如果您不想要所有常规的 dict 行为,那么您应该创建一个独立的类。然后,您可以给它一个 to_dict() 方法,或者更好的是,由于您确实希望转换为 JSON,因此创建一个自定义 JSON 编码器(必要时还需解码器),并将其用作 json.dumps()default 参数的使用。

json.dump()json.dumps() 中,可选参数 default 是一个可调用对象,应该返回对象的序列化版本或引发 TypeError (以获取默认行为)。


谢谢@Duncan,这正是我所想的。创建to_dict方法可能比子类化JSONEncoder更简单。 - Adam Pointer
说实话,我觉得扩展JSONEncoder的接口相当笨拙,并且在实际使用中它并不支持我想要做的那些扩展。 - Karl Knechtel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接