How do you call methods from superclass, like super in classic style ? 2017-05-14 9:45 GMT+02:00 Stephan Houben <stephan...@gmail.com>:
> FWIW, Javascript itself is moving away from this syntax in favour of a > more Python-like syntax based on the 'class' keyword. This was introduced > in EcmaScript 2015. > > Stephan > > Op 14 mei 2017 09:35 schreef "Simon Ramstedt" <simonramst...@gmail.com>: > > Hi, thanks a lot for your feedback! >> >> On Sun, May 14, 2017, 00:54 Brendan Barnwell <brenb...@brenbarn.net> >> wrote: >> >>> On 2017-05-13 21:07, Simon Ramstedt wrote: >>> > Hi, do you have an opinion on the following? >>> >>> My general opinion is that imitating JavaScript is almost always >>> a bad >>> idea. :-) >>> >>> > Wouldn't it be nice to define classes via a simple constructor function >>> > (as below) instead of a conventional class definition? >>> > >>> > *conventional*: >>> > | >>> > classMyClass(ParentClass): >>> > def__init__(x): >>> > self._x=x >>> > defmy_method(y): >>> > z=self._x+y >>> > returnz >>> > | >>> > >>> > >>> > *proposed*: >>> > >>> > | >>> > defMyClass(x): >>> > self=ParentClass() >>> > defmy_method(y): >>> > z=x+y >>> > returnz >>> > self.my_method=my_method # that's cumbersome (see comments below) >>> > returnself >>> > | >>> > >>> > >>> > Here are the pros and cons I could come up with for the proposed >>> method: >>> > >>> > (+) Simpler and more explicit. >>> >>> I don't really see how that's simpler or more explicit. In one >>> respect >>> it's clearly less explicit, as the "self" is implicit. >>> >>> > (+) No need to create attributes (like `self._x`) just to pass >>> something >>> > from `__init__` to another method. >>> >>> Attributes aren't just for passing things to other methods. >>> They're >>> for storing state. In your proposed system, how would an object mutate >>> one of its own attributes? It looks like "x" here is just stored in a >>> function closure, which wouldn't allow easy mutation. Also, how would >>> another object access the attribute from outside (as we currently do >>> with self.x)? You can say we'd only use this new attribute-free >>> approach when we want to pass a constructor argument that's used but >>> never mutated or accessed from outside, but that severely restricts the >>> potential use cases, and all it saves you is typing "self". >>> >> >> Attributes could be added to self just as in conventional classes if they >> are needed. >> >> >>> Relatedly, how is ParentClass itself defined? I don't see how >>> you >>> could bootstrap this without having a real class at the bottom of it >>> somehow (as your test script in fact does). >>> >> >> You could bootstrap with an object base class/constructor just as normal >> classes inherit from object. Also the normal class system should remain in >> any case in order not to break every python library. >> >>> >>> > (+) Default arguments / annotations for methods could be different for >>> > each class instance. Adaptive defaults wouldn't have to simulated with >>> a >>> > None. >>> >>> That seems as likely to be a negative as a positive. Having >>> different >>> instances with different default values could be confusing. This would >>> even allow different instances to define totally different methods (with >>> if-logic inside the function constructor), which would definitely be >>> confusing. >>> >> >> Different default values for different instances are a corner case but >> they are already happening by setting default to None. Defining >> different methods for different instances wouldn't be good but that is also >> possible with conventional classes (by adding functions to self in >> __init__). >> >> > (+) Class/instance level imports would work. >>> >>> How often is that really needed? >>> >> >> True, usually it doesn't matter. But when using big packages like >> tensorflow that take several seconds to load it can be annoying. Its always >> loaded when importing any library that uses it internally, because of >> module level imports that should be class/instance level. Even if we just >> wanted to do --help on the command line and needed that library before >> argparse for some reason. >> >> > (-/+) Speed: The `def`-based objects take 0.6 μs to create while the >>> > `class`-based objects take only 0.4 μs. For method execution however >>> the >>> > closure takes only 0.15 μs while the proper method takes 0.22 μs >>> (script >>> > <https://gist.github.com/rmst/78b2b0f56a3d9ec13b1ec6f3bd50aa9c>). >>> >>> I don't think you can really evaluate the performance impact of >>> this >>> alternative just based on a trivial example like that. >>> >>> Agree, I don't know really how well this would perform. >>> >> >> > (-/+) Checking types: In the proposed example above the returned object >>> > wouldn't know that it has been created by `MyClass`. There are a couple >>> > of solutions to that, though. The easiest to implement would be to >>> > change the first line to `self = subclass(ParentClass())` where the >>> > subclass function looks at the next item in the call stack (i.e. >>> > `MyClass`) and makes it the type of the object. Another solution would >>> > be to have a special rule for functions with capital first letter >>> > returning a single object to append itself to the list of types of the >>> > returned object. Alternatively there could be a special keyword e.g. >>> > `classdef` that would be used instead of `def` if we wouldn't want to >>> > rely on the name. >>> >>> Those special rules sound very hackish to me. >> >> >>> > (-) The current syntax for adding a function to an object is >>> > cumbersome. That's what is preventing me from actually using the >>> > proposed pattern. But is this really the only reason for not using it? >>> > And if so, wouldn't that be a good argument for enabling something like >>> > below? >>> > * >>> > * >>> > *attribute function definitions*: >>> > | >>> > defMyClass(x): >>> > self=ParentClass() >>> > defself.my_method(y): >>> > z=x+y >>> > returnz >>> > returnself >>> > | >>> > >>> > >>> > or alternatively*multiline lambdas*: >>> > >>> > | >>> > defMyClass(x): >>> > self=ParentClass() >>> > self.my_method=(y): >>> > z=x+y >>> > returnz >>> > returnself >>> > | >>> >>> To be honest, from all your examples, I don't really see what >>> the point >>> is. It's a different syntax for doing some of the same things the >>> existing class syntax does, while providing no apparent way to do some >>> important things (like mutating attributes). I think Python's existing >>> class syntax is simple, clear, and quite nice overall, and creating >>> class instances by calling a function instead of a class doesn't add >>> anything. In fact, even JavaScript has recently added classes to allow >>> programmers to move away from the old approach that you describe here. >>> Also, as I alluded to above, JavaScript is so terrible in so many ways >>> that the mere idea of imitating it inherently makes me skeptical; >>> there's almost nothing about JavaScript's design that couldn't be done >>> better, and most of what it does are things that Python already does >>> better and has done better for years. In short, I don't see any >>> advantages at all to doing classes this way, and there are some >>> non-negligible disadvantages. >>> >> >> Interesting, didn't know that about Javascript. I also don't like >> Javascript's prototypes very much but thought adding "JavaScript-like" to >> the title might help explain what I meant. >> >> Leaving the possible replacement for classes aside, do you have an >> opinion specifically about the following? >> >> def obj.my_function(a, b): >> ... >> >> as syntactic sugar for >> >> def my_function(a, b): >> ... >> >> obj.my_function = my_function >> >> In my experience this pattern comes actually up quite a bit. E.g. when >> working with these "symbolic" machine learning frameworks like theano or >> tensorflow. Apart from that it mixins very easy. >> >> What do you think are the odds of something like this actually making it >> into the Python and if greater than 0 in which timeframe? >> >> >> >>> -- >>> Brendan Barnwell >>> "Do not follow where the path may lead. Go, instead, where there is no >>> path, and leave a trail." >>> --author unknown >>> _______________________________________________ >>> Python-ideas mailing list >>> Python-ideas@python.org >>> https://mail.python.org/mailman/listinfo/python-ideas >>> Code of Conduct: http://python.org/psf/codeofconduct/ >> >> >> Thanks, >> >> Simon >> >>> >>> >> _______________________________________________ >> Python-ideas mailing list >> Python-ideas@python.org >> https://mail.python.org/mailman/listinfo/python-ideas >> Code of Conduct: http://python.org/psf/codeofconduct/ >> >> > _______________________________________________ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > > -- Antoine Rozo
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/