Type masquerading using dynamic base classes
Python allows us to construct new classes on-the-fly with type(). By (ab)using this feature we can construct a class that preserves its own interface while assuming all of the behaviour of an existing object. Useful for wrapping compound types such as dictionaries, lists, sets, etc. without having to proxy __getitem__, __iter__ and so on, or write a custom __getattr__.
One example of when this could be useful is a JSON-specific HTTP client object that assumes the type of the JSON data, while maintaining response-specific attributes such as headers and status:
import simplejson class Response(object): """A response object that masquerades as the decoded content type.""" def __new__(cls, content=None, headers=None, status=None): if content is not None: content = simplejson.loads(content) assumed_type = type(content) bases = (Response, assumed_type) name = assumed_type.__name__.title() + 'Response' cls = type(name, bases, {}) self = assumed_type.__new__(cls, content) self.assumed_type = assumed_type else: self = object.__new__(cls) return self def __init__(self, content=None, headers=None, status=None): if content is not None: super(Response, self).__init__(content) self.headers = headers self.status = status json_data = [ '{"foo": 1, "bar": 2}', '123', '123.5', '["foo", "bar"]', ] for data in json_data: response = Response(data, headers=[('Content-Type', 'application/json')], status=200) decoded = simplejson.loads(data) print response print ' Same type?', isinstance(response, type(decoded)) try: print ' Iteration:', print [i for i in response] except TypeError: print '(type does not support iteration)' print ' Headers:', response.headers print ' Status:', response.status print
Outputs this:
{u'foo': 1, u'bar': 2}
Same type? True
Iteration: [u'foo', u'bar']
Headers: [('Content-Type', 'application/json')]
Status: 200
123
Same type? True
Iteration: (type does not support iteration)
Headers: [('Content-Type', 'application/json')]
Status: 200
123.5
Same type? True
Iteration: (type does not support iteration)
Headers: [('Content-Type', 'application/json')]
Status: 200
[u'foo', u'bar']
Same type? True
Iteration: [u'foo', u'bar']
Headers: [('Content-Type', 'application/json')]
Status: 200

rss
Comments
No comments.