Variable arguments (*args, **kwargs): seeking elegance

John Ladasky john_ladasky at sbcglobal.net
Mon Oct 7 17:49:06 EDT 2013


Wow, Steven, that was a great, detailed reply.  I hope you will forgive me for shortcutting to the end, because I've been hacking away for a few hours and came to this very conclusion:

On Monday, October 7, 2013 2:13:10 PM UTC-7, Steven D'Aprano wrote:

> In general, you should aim to use either __new__ or __init__ but not  
> both, although that's not a hard law, just a guideline.

My problems were solved by adhering to using only __new__ in my ndarray subclasses, and avoiding __init__.  (If I used both methods, my arguments were passed to the object twice, once through each method.  That's weird!  It messed me up!  And I'm not sure what purpose it serves.)  The __new__ methods of my subclasses now call super().__new__ to handle the attributes and error checking which are common to all the classes, then handle the subclass-specific variables.

One wrinkle that I had to comprehend was that super().__new__ would be returning me a half-baked object on which I had to do more work.  I'm used to __init__, of course, which works on self.

OK, as for some other points:

> Don't forget ndarray.__array_finalize__, __array_wrap__ and  
> __array_prepare__.

I handle __array_finalize__ in my base class.  Also __reduce_ex__ and __setstate__, so that I can pickle and unpickle my array objects (which is necessary for multiprocessing work).  I haven't had time to deal with __array_wrap__ or __array_prepare__ yet, but so far my downstream code is working without these methods (crossing fingers).

> I am not an expert on numpy, but reading that page just makes me think 
> they're doing it all wrong, adding far too much complication. (I've 
> written code like that myself, but thank goodness I've had the sense to 
> throw it away and start again...). I'm trying to give them the benefit of 
> the doubt, but I've never liked the amount of DWIM cleverness in numpy, 
> and I think they would have been *much* better off having a clean 
> separation between the three ways of creating an array:
> 
> - the normal Python __new__ and __init__ mechanism
> - creating a view into an array
> - templating
> 
> instead of conflating the three into a single mechanism.

I agree, I always find it complicated to wrap my head around these complexities.  But I simply can't live without numpy!

And finally:

> sneaky = kwargs.pop('sneaky', True)  # optional

I don't know whether to be excited or embarrassed that I can still learn things about the basics of Python... I've never used the optional argument of dict.pop().  Cool!  Thanks.



More information about the Python-list mailing list