0

I found this quirk while checking out how to use super.


In [1]: super?                                                                                                      
Init signature: super(self, /, *args, **kwargs)
Docstring:     
super() -> same as super(__class__, <first argument>)
...

Note that the first example uses __class__ directly.

And somehow, __class__ can be used inside instance methods:

class Test():
    def __init__(self):
        print(__class__)
    def foo(self):
        print(__class__)
    def bar(self):
        print(bar)

t = Test()  # <class '__main__.Test'>
t.foo()  # <class '__main__.Test'>
t.bar()  # NameError: name 'bar' is not defined

Can anyone explain why this is the case?

sshashank124
  • 31,495
  • 9
  • 67
  • 76
buckle2000
  • 139
  • 8
  • 2
    @DYZ: No. For one thing, methods and variables defined in a class body are not accessible by bare name within method bodies. For another, `__class__` is not actually defined in the class body. (`Test.__class__` is a valid expression, but refers to something completely different. `self.__class__` is also a valid expression, but refers to something subtly different in a way that has caused many bugs.) This `__class__` is a weird special case used for `super` support. – user2357112 Dec 30 '19 at 08:12
  • Docs: https://docs.python.org/3/reference/datamodel.html#creating-the-class-object Related: https://stackoverflow.com/questions/36993577/schr%C3%B6dingers-variable-the-class-cell-magically-appears-if-youre-checking/ – user2357112 Dec 30 '19 at 08:14

1 Answers1

0

So, it is a quirk for the compiler to find the parent class.

From Python Data Model:

__class__ is an implicit closure reference created by the compiler if any methods in a class body refer to either __class__ or super. This allows the zero argument form of super() to correctly identify the class being defined based on lexical scoping, while the class or instance that was used to make the current call is identified based on the first argument passed to the method.

buckle2000
  • 139
  • 8