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