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?