Working with Sanic (async web framework in Python), I was trying to add custom data to a request:
request.user = 'A nice user'
But I was not able to, request is of type Request and does not allow this.
Looking at the source code for the Request class:
class Request(dict):
"""Properties of an HTTP request such as URL, headers, etc."""
__slots__ = (
'app', 'headers', 'version', 'method', '_cookies', 'transport',
'body', 'parsed_json', 'parsed_args', 'parsed_form', 'parsed_files',
'_ip', '_parsed_url', 'uri_template', 'stream', '_remote_addr',
'_socket', '_port', '__weakref__'
)
Looking up the internet, this dict inheritance has been added through a pull request to allow attaching data to a Request object.
So the recommended approach is:
request['user'] = 'A nice user'
This is all fine, I understand how it works.
However, I am confused by the usage of __slots__ on this class since it inherits from dict.
Another way to allow attaching data to this class' instances would have been to remove the __slots__ altogether (then we could have done request.user = ...).
The way I understand things, one use of __slots__ is to reduce the memory footprint of the object, preventing the creation of the __dict__ attribute.
But if we are inheriting from a dictionary does this still make sense?
Doing some command line tests with sys.getsizeof suggests it does not, but I'm not sure I can trust these.
How does this approach to allow adding data on the instances (using slots, inheriting from dict) compare to:
Not using slots, not inheriting from
dict.
Would attribute access be slower (could not verify this in command line tests)?Adding
'__dict__'to__slots__, not inheriting fromdict.
This answer on slots suggests it would give us the behavior we want.
Are there some other reasons why one would want to use __slots__ and inherit from dict here?