Reputation: 2391
class LoggingDict(dict):
# Simple example of extending a builtin class
def __setitem__(self, key, value):
logging.info('Setting %r to %r' % (key, value))
super(LoggingDict, self).__setitem__(key, value)
class LoggingDict(dict):
# Simple example of extending a builtin class
def __setitem__(self, key, value):
logging.info('Setting %r to %r' % (key, value))
super().__setitem__(key, value)
illustrate the fact that Python 2's super
requires explicit class and self
arguments (but Python 3's doesnt). Why is that? It seems like an irritating limitation.
Upvotes: 0
Views: 146
Reputation: 2391
The link in AKS' comment provides the answer here:
Lets say in the Python 2 example I thought "I don't like that explicit class reference. What if I change the name of the class or move this code and forget to update it?". Lets say I thought, a-ha, I'll replace the explicit class name with self.__class__
and wrote:
class LoggingDict(dict):
# Simple example of extending a builtin class
def __setitem__(self, key, value):
logging.info('Setting %r to %r' % (key, value))
super(self.__class__, self).__setitem__(key, value)
Now I create a subclass called SpecialisedLoggingDict
of LoggingDict
(which doesn't override __setitem__
), instantiate it and call __setitem__
on it.
Now self
refers to an instance of SpecialisedLoggingDict
, so the super
returns LoggingDict
, and we go straight back into LoggingDict.__setitem__
, entering infinite recursion.
The essential point is that in Python 2 a method doesn't really know which class it was defined in, it only knows the class of the instance on which it's being called. Python 3 does compile-time "magic", adding a __class__
cell to functions so that super()
can be used without the explicit class reference.
Upvotes: 1