From: Tim H. <tim...@ie...> - 2003-09-24 22:27:59
|
Hi Todd, There are three ways to spell "defer to me" on the table (the precise details of each spelling are, of course, still open for debate): 1. numarray.defer_to(my_class) 2. class ArrayLike(numarray.DeferTo): # ... 3. class ArrayLike: _numarray_defer_to = True # ... I'd prefer a non-registration solution since those are both aesthetically displeasing and leave you open to the situation where a class in module A gets registered by module B, but module C expects it not to be registered and everything breaks. Not all that likely, I admit, but let's avoid the registration version if we can. The other two solutions are almost equivalent. The one case where 3 has an edge over 2 is if I have an object (not a class), I could potentially set a _numarray_defer_to on the object before passing it to numarray without having to mess with the class of the object at all. YAGNI, though. The advantage of 2 in my view is that it *does* force you to subclass. With 3, there will be the temptation to poke into some other module and set _numarray_defer_to on some poor unsuspecting class. This has the same disadvantage as 1, that it could confuse some other poor unsuspecting module. The correct way to do get a deferred class from a third party module is to import and subclass. This works with either 2 or 3:: import A class Klass2(a.Klass, numarray.DeferTo): #2 #... class Klass3(a.Klass): #3 the good way _numarray_defer_to = True # ... A.Klass._numarray_defer_to = True #3 the evil way. Version 2 is cleaner and encourages you to do the right thing, so I'd prefer that solution. regards, -tim Todd Miller wrote: >On Mon, 2003-09-22 at 19:27, Tim Hochberg wrote: > > > >>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) >> >> >> >> > >I like the core idea a lot. My only doubt is whether forcing the use of >inheritance is appropriate / a good thing. We might also consider >spelling it like: > >class MyArrayLikeClass: > _numarray_defer_to_me = True > >class NumArray: > def __mul__(self, operand): > if hasattr(operand, "_numarray_defer_to_me"): > return operand.__rmul__(self) > else: > return ufunc.multiply(self, 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. >> >> > >Sounds YAGNI to me. > > > >>Avoiding registration is appealing. >> >> > >Good to have this seconded. > > > >>-tim >> >> >> > >All in all, great ideas! > >Todd > > > |