Make __class__ (and maybe other magic variables) visible to functions that was defined outside a class, but then rebound into a class?
For example, the following code would report an error: class base(): def foo(self) -> None: print('Base!') def placement(self) -> None: super().foo() class child(base): def foo(self) -> None: pass foo = placement child().foo() RuntimeError: super(): __class__ cell not found However, it would be OK if `placement` is defined inside the class: class base(): def foo(self) -> None: print('Base!') class child(base): def placement(self) -> None: super().foo() def foo(self) -> None: pass foo = placement child().foo() which prints: Base! I think it would be natural if those functions that was defined outside a class, but then rebound into a class, can see magic variables like __class__ that are only shared by those functions defined inside a class. Thank you!
How would the interpreter know which Class the rebound “belonged” to? For example, that same function could be added to two different classes— then what would super() do? BTW, the Python 2 style of calling súper with the class and instance as arguments might work in the case :-) As an experiment, try adding the placement method to a different class altogether and see what you get. class another: foo = child.placement -CHB On Tue, Jul 27, 2021 at 8:16 PM Yua <uncha21@163.com> wrote:
For example, the following code would report an error:
class base(): def foo(self) -> None: print('Base!')
def placement(self) -> None: super().foo()
class child(base): def foo(self) -> None: pass foo = placement
child().foo()
RuntimeError: super(): __class__ cell not found
However, it would be OK if `placement` is defined inside the class:
class base(): def foo(self) -> None: print('Base!')
class child(base): def placement(self) -> None: super().foo() def foo(self) -> None: pass foo = placement
child().foo()
which prints:
Base!
I think it would be natural if those functions that was defined outside a class, but then rebound into a class, can see magic variables like __class__ that are only shared by those functions defined inside a class.
Thank you!
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/GTTD2C... Code of Conduct: http://python.org/psf/codeofconduct/
-- Christopher Barker, PhD (Chris) Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
Thank you for bringing that to my attention! I think maybe can the interpreter decide whether __class__ etc. should be added to the environment with regard to how the function is called? The interpreter does not provide __class__ etc. for plain placement() calls, but provide them at calls like child().foo() - when the callee function is named as a class method. Dynamically. #2/3 Also thanks for the idea of super(type(self), self) - that works! Like this, class base(): def foo(self) -> None: print('Base!') def placement(self) -> None: super(type(self), self).foo() class child(base): def foo(self) -> None: pass foo = placement child().foo() But in a more complex case where the base class calls also calls super() this way, it runs into an infinite recursion. Like: |class base(): def foo(self) -> None: print('Base!') def placement(self) -> None: super(type(self), self).foo() class child(base): def foo(self) -> None: pass foo = placement class child2(child): def foo(self) -> None: pass foo = placement child2().foo()| || #3/3 I also found it interesting that there are different results from rebinding a class method with a function defined outside the class, and with a function defined inside the class. Version 1 and version 2 results in the same error message: class base: def foo(self) -> None: print('Base!') class child(base): def foo(self) -> None: super().foo() class another(base): foo = child.foo another().foo() Version 2: class base: def foo(self) -> None: print('Base!') class child(base): def foo(self) -> None: print('Child!') def placement(self) -> None: super().foo() foo = placement class another(base): foo = child.foo another().foo() which all result in a mysterious TypeError: super(type, obj): obj must be an instance or subtype of type I guess there is an argument issue. Maybe foo() is called as a classmethod? While this, class base: def foo(self) -> None: print('Base!') def placement(self) -> None: super().foo() class child(base): def foo(self) -> None: print('Child!') foo = placement class another(base): foo = child.foo another().foo() Results in the familiar RuntimeError: super(): __class__ cell not found. Thank you! Yua On 28/07/2021 11:29, Christopher Barker wrote:
How would the interpreter know which Class the rebound “belonged” to?
For example, that same function could be added to two different classes— then what would super() do?
BTW, the Python 2 style of calling súper with the class and instance as arguments might work in the case :-)
As an experiment, try adding the placement method to a different class altogether and see what you get.
class another: foo = child.placement
-CHB
On Tue, Jul 27, 2021 at 8:16 PM Yua <uncha21@163.com <mailto:uncha21@163.com>> wrote:
For example, the following code would report an error:
class base(): def foo(self) -> None: print('Base!')
def placement(self) -> None: super().foo()
class child(base): def foo(self) -> None: pass foo = placement
child().foo()
RuntimeError: super(): __class__ cell not found
However, it would be OK if `placement` is defined inside the class:
class base(): def foo(self) -> None: print('Base!')
class child(base): def placement(self) -> None: super().foo() def foo(self) -> None: pass foo = placement
child().foo()
which prints:
Base!
I think it would be natural if those functions that was defined outside a class, but then rebound into a class, can see magic variables like __class__ that are only shared by those functions defined inside a class.
Thank you!
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org <mailto:python-ideas@python.org> To unsubscribe send an email to python-ideas-leave@python.org <mailto:python-ideas-leave@python.org> https://mail.python.org/mailman3/lists/python-ideas.python.org/ <https://mail.python.org/mailman3/lists/python-ideas.python.org/> Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/GTTD2C... <https://mail.python.org/archives/list/python-ideas@python.org/message/GTTD2CSWNCSH2UW657YK3M7GPSUOKWYS/> Code of Conduct: http://python.org/psf/codeofconduct/ <http://python.org/psf/codeofconduct/>
-- Christopher Barker, PhD (Chris)
Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
On Wed, Jul 28, 2021 at 3:56 PM Yua <uncha21@163.com> wrote:
Thank you for bringing that to my attention!
I think maybe can the interpreter decide whether __class__ etc. should be added to the environment with regard to how the function is called?
The interpreter does not provide __class__ etc. for plain placement() calls, but provide them at calls like child().foo() - when the callee function is named as a class method. Dynamically.
No, because it can't know WHICH class it should be referencing. The entire point of the name __class__ is that it refers to the class being defined, so it has to be added at compilation time. ChrisA
participants (3)
-
Chris Angelico
-
Christopher Barker
-
Yua