17

Coding this day, which of the above is preferred and recommended (both in Python 2 and 3) for subclassing?

I read that UserList and UserDict have been introduced because in the past list and dict couldn't be subclassed, but since this isn't an issue anymore, is it encouraged to use them?

vaultah
  • 44,105
  • 12
  • 114
  • 143
linkyndy
  • 17,038
  • 20
  • 114
  • 194

2 Answers2

21

Depending on your usecase, these days you'd either subclass list and dict directly, or you can subclass collections.MutableSequence and collections. MutableMapping; these options are there in addition to using the User* objects.

The User* objects have been moved to the collections module in Python 3; but any code that used those in the Python 2 stdlib has been replaced with the collections.abc abstract base classes. Even in Python 2, UserList and UserDict are augmented collections.* implementations, adding methods list and dict provide beyond the basic interface.

The collections classes make it clearer what must be implemented for your subclass to be a complete implementation, and also let you implement smaller subsets (such as collections.Mapping, implementing a read-only mapping, or collections.Sequence for a tuple-like object).

The User* implementations should be used when you need to implement everything beyond the basic interface too; e.g. if you need to support addition, sorting, reversing and counting just like list does.

For anything else you are almost always better off using the collections abstract base classes as a basis; the built-in types are optimised for speed and are not that subclass-friendly. For example, you'll need to override just about every method on list where normally a new list is returned, to ensure your subclass is returned instead.

Only if you need to build code that insists on using a list or dict object (tested by using isinstance() is subclassing the types an option to consider. This is why collections.OrderedDict is a subclass of dict, for example.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    And what difference does subclassing each of them bring to subclassing their counterpart? Why should I use `list` in favor of `collections.Sequence` or vice-versa? – linkyndy Aug 23 '14 at 17:54
  • 2
    @AndreiHorak:- Just to add you may check one issue which will help you understand more: http://bugs.python.org/issue5402 – Rahul Tripathi Aug 23 '14 at 17:59
4

No they are not encouraged anymore. You should not use the UserDict class as it is deprecated. The docs says you can just subclass dict directly. The userdict module is gone in Python 3.0

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • 1
    In the link you've provided there is `Moved to the 'collections' module.` specified. If they are not encouraged anymore, why were they kept in the latest versions? What do they bring different than the standard types? – linkyndy Aug 23 '14 at 17:49
  • 2
    @AndreiHorak:- From Python version 2.6, it is recommended to use `collections.MutableMapping` and `collections.Sequence` instead. – Rahul Tripathi Aug 23 '14 at 17:52
  • 4
    @AndreiHorak: they are not really deprecated as it turns out the classes have their uses; it is easier to subclass `UserList` and get sorting and (in Python 2) slicing to work correctly vs having to override everything on the `list` type. – Martijn Pieters Aug 23 '14 at 18:15
  • 1
    No. As [the docs say](https://docs.python.org/3/library/collections.html#collections.UserDict), the `User*` classes can be easier to work with when access to the underlying data structure is needed because it is accessible as an attribute. – Jeyekomon Jun 14 '21 at 13:47