On Fri, Aug 04, 2017 at 10:20:55AM -0300, Joao S. O. Bueno wrote: > Had not this been discussed here earlier this year? > > (And despite there being perceived dangers to readability in the long term, > was accepted?) > > Here it is on an archive: > https://mail.python.org/pipermail/python-ideas/2017-February/044551.html
I don't read this as the same proposal. For starters, I don't believe that it was intended to allow monkey-patching of builtins. Another is that the syntax is much more explicit about where the method is going: def MyClass.method(self, arg): ... is clearly a method of MyClass. There was, if I recall, some open discussion of whether arbitrary assignment targets should be allowed: def module.func(x or None)[23 + n].attr.__type__.method(self, arg): ... or if we should intentionally limit the allowed syntax, like we do for decorators. My vote is for intentionally limiting it to a single dotted name, like MyClass.method. > And anyway - along that discussion, despite dislikng the general idea, I > got convinced that > creating an outside method that makes "super" or "__class__" work was > rather complicated. Complicated is an understatement. It's horrid :-) Here's the problem: we can successfully inject methods into a class: # -----%<----- class Parent: def spam(self): return "spam" class Child(Parent): def food(self): return 'yummy ' + self.spam() c = Child() c.food() # returns 'yummy spam' as expected # inject a new method def spam(self): return 'spam spam spam' Child.spam = spam c.food() # returns 'yummy spam spam spam' as expected # -----%<----- But not if you use the zero-argument form of super(): # -----%<----- del Child.spam # revert to original def spam(self): s = super().spam() return ' '.join([s]*3) Child.spam = spam c.food() # -----%<----- This raises: RuntimeError: super(): __class__ cell not found This is the simplest thing I've found that will fix it: # -----%<----- del Child.spam # revert to original again def outer(): __class__ = Child def spam(self): s = super().spam() return ' '.join([s]*3) return spam Child.spam = outer() c.food() # returns 'yummy spam spam spam' as expected # -----%<----- It's probably possibly to wrap this up in a decorator that takes Child as argument, but I expect it will probably require messing about with the undocumented FunctionType constructor to build up a new closure from the bits and pieces scavenged from the decorated function. > Maybe we could just have a decorator for that, that would properly create > the __class__ cell? I expect its possible. A challenge to somebody who wants to get their hands dirty. -- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/