[Python-Dev] Problems with the new super()
Guido van Rossum
guido at python.org
Wed Apr 30 23:57:32 CEST 2008
The staticmethod thing isn't new; that's also the case in 2.x.
The super() thing is a case of practicality beats purity. Note that
you pay a small but measurable cost for the implicit __class__ (it's
implemented as a "cell variable", the same mechanism used for nested
scopes) so we wouldn't want to introduce it unless it is used.
On Wed, Apr 30, 2008 at 2:46 PM, Armin Ronacher
<armin.ronacher at active-4.com> wrote:
> Hi all,
>
> I blogged about that topic today which turned out to be a very bad idea,
> so I summarize it for the mailinglist here to hopefully start a discussion
> about the topic, which I think is rather important.
>
> In the last weeks something remarkable happened in the Python3 sources:
> self kinda became implicit. Not in function definitions, but in super
> calls. But not only self: also the class passed to `super`. That's
> interesting because it means that the language shifts into a completely
> different direction.
>
> `super` was rarely used in the past, mainly because it was weird to use.
> In the most common use case the current class and the current instance
> where passed to it, and the super typed returned looked up the parent
> methods on the MRO for you. It was useful for multiple inheritance and
> mixin classes that don't know their parent but confusing for many. I can
> see that a replacement is a good idea, but I'm not so sure if the current
> implementation is the way to go.
>
> The main problem with replacing `super(Foo, self).bar()` with something
> like `super.bar()` is obviously that self is explicit and the class (in
> that case Foo) can't be determined by the caller. Furthermore the Python
> principle was always against functions doing stack introspection to find
> the caller. There are few examples in the stdlib or builtins that do
> some sort of caller introspection. Those are the special functions
> `vars`, `locals`, `gloabal`, `vars` and some functions in the inspect
> module. And all of them do nothing more than getting the current frame
> and accessing the dict of locals or globals. What super in current
> Python 3 builds does goes way beyond that.
>
> The implementation of the automatic super currently has two ugly details
> that I think violate the Python Zen: The bytecode generated is differently
> if the name "super" is used in the function. `__class__` is only added as
> cell to the code if `super` or `__class__` is referenced. That and the fact
> that `f_localsplus` is completely unavailable from within python makes the
> whole process appear magical.
>
> This is way more magical than anything we've had in Python in the past and
> just doesn't fit into the language in my opinion. We do have an explicit
> self in methods and methods are more or less just functions. Python's
> methods are functions, just that a descriptor puts a method object around
> it to pass the self as first arguments. That's an incredible cool thing
> to have and makes things very simple and non-magical. Breaking that
> principle by introducing an automatic super seems to harm the concept.
>
> Another odd thing is that Python 3 starts keeping information on the C
> layer we can't access from within Python. Super is one example, another
> good one are methods. They don't have a descriptor that wraps them if
> they are accessed via their classes. This as such is not a problem as you
> can call them the same (just that you can call them with completely
> different receivers now) but it becomes a problem if some of the functions
> are marked as staticmethods. Then they look completely the same when
> looking at them from a classes perspective:
>
> | >>> class C:
> | ... normal = lambda x: None
> | ... static = staticmethod(lambda x: None)
> | ...
> | >>> type(C.normal) is type(C.static)
> | True
> | >>> C.normal
> | <function <lambda> at 0x4da150>
>
> As far as I can see a documentation tool has no chance to keep them apart
> even though they are completely different on an instance:
>
> | >>> type(C().normal) is type(C().static)
> | False
> | >>> C().normal
> | <bound method C.<lambda> of <__main__.C object at 0x4dbcf0>>
> | >>> C().static
> | <function <lambda> at 0x4da198>
>
> While I don't knwo about the method thing, I think an automatic super should
> at least be implementable from within Python. I could imagine that by adding
> __class__ and __self__ to scopes automatically a lot of that magic could be
> removed.
>
> Regards,
> Armin
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org
>
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-Dev
mailing list