[Tutor] super() vs. explicitly calling base class?

Eryk Sun eryksun at gmail.com
Sat Sep 21 22:44:47 EDT 2019


On 9/21/19, Mats Wichmann <mats at wichmann.us> wrote:
>
> Would just like to remind: that function there which prints "This is the
> Base class!" - isn't really "in" it.  The def statement causes a
> function object to be created, and a reference to that function object,
> with the name "__init__", goes into the dictionary that was created by
> the Base class definition. But it has no phyical attachment to Base...

That's generally true. But note that, in the context of a class
definition, if a function references the __class__ special name,
either directly by name (without assignment) or indirectly by calling
super(), it gets defined with a closure reference to the defining
class [1].

    >>> class A:
    ...     def eggs(self):
    ...         pass
    ...     def spam(self):
    ...         super()
    ...     def foo(self):
    ...         return __class__

    >>> A.eggs.__code__.co_freevars
    ()

    >>> A.spam.__code__.co_freevars
    ('__class__',)
    >>> A.spam.__closure__[0].cell_contents is A
    True

    >>> A.foo.__code__.co_freevars
    ('__class__',)
    >>> A.foo.__closure__[0].cell_contents is A
    True
    >>> A.foo('whatever') is A
    True

This only pertains to defining a function in the context of a class
definition. Otherwise __class__ is not reserved. Of course, as a
dunder name, it should always be reserved by convention.

    >>> def f(self):
    ...     __class__
    ...
    >>> f.__code__.co_freevars
    ()
    >>> f.__code__.co_names
    ('__class__',)

[1] https://docs.python.org/3/reference/datamodel.html#creating-the-class-object


More information about the Tutor mailing list