Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subclassing python dictionaries

I am using ElasticSearch in my Python application and want to be able to create a reusable dictionary object that represents a query. The JSON structures are described here http://pulkitsinghal.blogspot.co.uk/2012/02/how-to-use-elasticsearch-query-dsl.html and I am using PyES to query the search server. With PyES we can pass a dict object which gets jsonified before sending to the server. I want to create a library of common queries where only the actual query term changes, so I thought I would subclass dict so I could pass in the query term via the constructor, for example, and when the dict gets jsonified I would end up with something like this:

{
  "fields": [
    "name",
    "shortDescription",
    "longDescription"
  ],
  "query": {
    "query_string": {
      "fields": [
        "name"
      ],
      "query": query_term,
      "use_dis_max": true
    }
  }
}

How would I do this? Is it true that only instance members get returned via __dict__ if so would I have to set up this data structure in the constructor? Is this the best way of doing this or should I create a class that does not extend dict and just create a to_dict() method that returns a dictionary in the correct structure?

Answer:

This seems to work fine, any suggestions for making this more 'pythonic' will be appreciated! (Yes I know there are no doc strings)

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
like image 455
Adam Pointer Avatar asked Aug 10 '26 09:08

Adam Pointer


1 Answers

If you don't want all of the normal dict behaviour then you should definitely just create a separate class. You can then either give it a to_dict() method, or better since you really want to convert to json create a custom json encoder (and if required decoder) to use with the default argument of json.dumps().

In json.dump() and json.dumps() the optional argument default is a callable that should either return a serialized version of the object or raise TypeError (to get the default behaviour).

like image 96
Duncan Avatar answered Aug 12 '26 23:08

Duncan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!