Fernando Perez wrote:
Tim Hochberg wrote:
I agree that using try/except is probably not worth the danger. However, I think I'd prefer the inverse of what you propose. That is:
def __mul__(self, operand): if isinstance(operand, _numarray_nondeferred_types): self.__mul__(operand) else: operand.__rmul__(self)
and of course a dont_defer_to registration function. Hopefully with a better name. The choice comes down to whether we defer by default or handle by default. I'm marginally on the side of deferring, but don't feel too strongly either way. Either one would be a big improvement.
Perhaps someone else out there has some profound thoughts.
Well, certainly not profound, but here's my proverbial $0.02. I tend to really dislike separate registration functions, since they reek too much of 'programming by side-effect'. Why not put the necessary information into a keyword argument to the constructor? Once a sensible default is chosen, then it can be overridden with 'defers=True' (if the default was False) at __init__ time, for example. Since this is a class-wide issue, perhaps it may make more sense to handle it via a meta-class mechanism. But I'm not an expert on metaclasses, so I'll shut up there :)
I actually have no idea how you plan to make keyword arguments work here, perhaps you could explain that in more detail. Metaclasses are overkill, but a mixin, marker class could be used. That is, when designing a class for use with numarray, one would derive a class from a marker class in numarray::
class MyArrayLikeClass(numarray.DeferToMe): ....
Hmmm. That's not too bad. Todd, what do you think about using this logic::
def __mul__(self, operand): if isinstance(operand, DeferToMe): operand.__rmul__(self) else: self.__mul__(operand)
The only case where I see a potential problem is an old-style C-extenstion that can't be subclassed. I think that might be a case of YAGNI though. Avoiding registration is appealing.
-tim