On Mar 6, 2015, at 5:21, Nick Coghlan
On 4 March 2015 at 03:28, Ethan Furman
wrote: On 03/02/2015 02:57 AM, Martin Teichmann wrote:
class Soliton(type): def __new__(cls, name, bases, ns): self = super().__new__(name, bases, ns) return self()
class A(metaclass=Soliton): def f(self): print(__class__)
This should be `self.__class__`, yes?
No, it's printing out the type referenced from the definition time cell*, rather than the type of the object actually passed in to the method.
Cheers, Nick.
P.S. *For anyone that isn't already aware, the general gist of how that works:
* The compiler actually special cases "super()" and "__class__" in method bodies * If it sees either of them, it implicitly adds a "__class__" cell reference to the function * In the "super()" case, the call is implicitly rewritten as "super(<first param>, __class__)" * __class__ is later filled in with a reference to the class being defined, once that actually exists
I think it's clearer to explain it as: Every method has a nonlocal variable named __class__ that refers to the class it's defined in. (As an optimization, CPython doesn't create a closure cell for __class__ if the method body doesn't need it.) The only problem with this definition is that someone implementing Python and writing type.__new__ has to know at exactly what point the __class__ cell becomes available. But I don't think an implementation that made it available too early would be considered broken, would it?
In my view, that's never going to win any awards for "elegance in language design", but it makes super() so much easier to use I'm happy to tell my sense of aesthetics to be quiet :)
-- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/