On Tuesday 28 October 2003 04:16 pm, Guido van Rossum wrote: > > So perhaps for 2.3 we should just apologetically note the anomaly > > in the docs, and for 2.4 forbid the former case, i.e., require both > > __mul__ AND __rmul__ to exist if one wants to code sequence > > classes that can be multiplied by integers on either side...? > > > > Any opinions, anybody...? > > What's wrong with the status quo? So 3*x is undefined, and it happens > to return x*3. Is that so bad? Where is it specified that 3*x "is undefined" when x's type exposes __mul__ but not __rmul__ ? Sorry, I don't understand the viewpoint you seem to imply here. If x's type exposed no __add__ but "it just so happened" that x+23 always returned 12345 -- while every other addition, as expected, failed -- would you doubt the lack of a normal and reasonably expected exception is bad? I think that if Python returns "arbitrary" results, rather than raising an exception, for operations that "should" raise an exception, that is surely very bad -- it makes it that much harder for programmers to debug the programs they're developing. If there's some doubt about the words I've put in hyphens -- that treating x*y just like y*x only for certain values of type(y) isn't arbitrary or shouldn't raise -- then we can of course discuss this, but isn't the general idea correct? Now, the docs currently say, about sequences under http://www.python.org/doc/current/ref/sequence-types.html : """ sequence types should implement ... multiplication (meaning repetition) by defining the methods __mul__(), __rmul__() and __imul__() described below; they should not define __coerce__() or other numerical operators. """ So, a sequence-emulating type that implements __mul__ but not __rmul__ appears to violate that "should". The description of __mul__ and __rmul__ referred to seems to be that at http://www.python.org/doc/current/ref/numeric-types.html . It says that methods corresponding to operations not supported by a particular kind of number should be left undefined (as opposed to the behavior of _attempts at those operations_ being undefined), so if I had a hypothetical number type X such that, for x instance of X and an integer k, x*k should be supported but k*x shouldn't, isn't this a recommendation to not write __rmul__ in X ...? Besides, this weird anomaly is typical of newstyle classes only. Consider: >>> class X: ... def __mul__(self, other): return 23 ... >>> x=X() >>> x*7 23 >>> 7*x Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: unsupported operand type(s) for *: 'int' and 'instance' >>> ALL wonderful, just as expected, hunky-dory. But now, having read that newstyle classes are better, I want to make X newstyle -- can't see any indication in the docs that I shouldn't -- and...: >>> class X(object): ... def __mul__(self, other): return 23 ... >>> x=X() >>> x*7 23 >>> 7*x 23 >>> *eep*! Yes, it DOES seem to be that this is QUITE bad indeed. Alex
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4