<div dir="ltr"><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px">Hi, do you have an opinion on the following?<br><br>Wouldn't it be nice to define classes via a simple constructor function (as below) instead of a conventional class definition?</div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><b>conventional</b>:</div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px">    </div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:1px solid rgb(187,187,187);word-wrap:break-word"><code style="margin:0px;padding:0px;border:0px"><div style="margin:0px;padding:0px;border:0px"><span style="margin:0px;padding:0px;border:0px">   <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">class</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,0,102)">MyClass</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">(</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,0,102)">ParentClass</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">):</span><span style="margin:0px;padding:0px;border:0px"><br>     <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">def</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>__init__</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">(</span><span style="margin:0px;padding:0px;border:0px">x</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">):</span><span style="margin:0px;padding:0px;border:0px"><br>       <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">self</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">.</span><span style="margin:0px;padding:0px;border:0px">_x<span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">=</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>x<br>     <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">def</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>my_method</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">(</span><span style="margin:0px;padding:0px;border:0px">y</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">):</span><span style="margin:0px;padding:0px;border:0px"><br>        z<span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">=</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">self</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">.</span><span style="margin:0px;padding:0px;border:0px">_x<span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">+</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>y<br>       <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">return</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>z</span></div></code></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><b>proposed</b>:</div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:1px solid rgb(187,187,187);word-wrap:break-word"><code style="margin:0px;padding:0px;border:0px"><div style="margin:0px;padding:0px;border:0px"><span style="margin:0px;padding:0px;border:0px">   <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">def</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,0,102)">MyClass</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">(</span><span style="margin:0px;padding:0px;border:0px">x</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">):</span><span style="margin:0px;padding:0px;border:0px"><br>     <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">self</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">=</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,0,102)">ParentClass</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">()</span><span style="margin:0px;padding:0px;border:0px"><br>     <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">def</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>my_method</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">(</span><span style="margin:0px;padding:0px;border:0px">y</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">):</span><span style="margin:0px;padding:0px;border:0px"><br>        z<span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">=</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>x<span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">+</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>y<br>       <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">return</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>z<br>     <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">self</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">.</span><span style="margin:0px;padding:0px;border:0px">my_method<span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">=</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>my_method  </span><span style="margin:0px;padding:0px;border:0px;color:rgb(136,0,0)"># that's cumbersome (see comments below)</span><span style="margin:0px;padding:0px;border:0px"><br>     <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">return</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">self</span></div></code></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px">Here are the pros and cons I could come up with for the proposed method:</div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px">(+) Simpler and more explicit.</div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px">(+) No need to create attributes (like `self._x`) just to pass something from `__init__` to another method.</div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px">(+) Default arguments / annotations for methods could be different for each class instance. Adaptive defaults wouldn't have to simulated with a None.<br><br>(+) Class/instance level imports would work.<br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px">(-/+) 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 (<a href="https://gist.github.com/rmst/78b2b0f56a3d9ec13b1ec6f3bd50aa9c" target="_blank" rel="nofollow" style="color:rgb(102,17,204);margin:0px;padding:0px;border:0px;text-decoration:none">script</a>).</div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px">(-/+) 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.</div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px">(-) 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?</div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><b><br></b></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><b>attribute function definitions</b>:<br><span style="margin:0px;padding:0px;border:0px;font-family:Arial,Helvetica,sans-serif"> </span></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:1px solid rgb(187,187,187);word-wrap:break-word"><code style="margin:0px;padding:0px;border:0px"><div style="margin:0px;padding:0px;border:0px"><span style="margin:0px;padding:0px;border:0px">   <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">def</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,0,102)">MyClass</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">(</span><span style="margin:0px;padding:0px;border:0px">x</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">):</span><span style="margin:0px;padding:0px;border:0px"><br>     <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">self</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">=</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,0,102)">ParentClass</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">()</span><span style="margin:0px;padding:0px;border:0px"><br>     <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">def</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">self</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">.</span><span style="margin:0px;padding:0px;border:0px">my_method</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">(</span><span style="margin:0px;padding:0px;border:0px">y</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">):</span><span style="margin:0px;padding:0px;border:0px"><br>        z<span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">=</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>x<span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">+</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>y<br>       <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">return</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>z<br>     <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">return</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">self</span></div></code></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px">or alternatively<span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span><b>multiline lambdas</b>:</div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:1px solid rgb(187,187,187);word-wrap:break-word"><code style="margin:0px;padding:0px;border:0px"><div style="margin:0px;padding:0px;border:0px"><span style="margin:0px;padding:0px;border:0px">   <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">def</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,0,102)">MyClass</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">(</span><span style="margin:0px;padding:0px;border:0px">x</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">):</span><span style="margin:0px;padding:0px;border:0px"><br>     <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">self</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">=</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,0,102)">ParentClass</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">()</span><span style="margin:0px;padding:0px;border:0px"><br>     <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">self</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">.</span><span style="margin:0px;padding:0px;border:0px">my_method<span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">=</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">(</span><span style="margin:0px;padding:0px;border:0px">y</span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">):</span><span style="margin:0px;padding:0px;border:0px"><br>        z<span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">=</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>x<span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(102,102,0)">+</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>y<br>       <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">return</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span>z<br>     <span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">return</span><span style="margin:0px;padding:0px;border:0px"><span class="inbox-inbox-inbox-inbox-Apple-converted-space"> </span></span><span style="margin:0px;padding:0px;border:0px;color:rgb(0,0,136)">self</span></div></code></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px">Cheers,</div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px"><br></div><div style="font-family:monospace;background-color:rgb(250,250,250);margin:0px;padding:0px;border:0px">Simon</div></div>