Re: Thoughts and proposals about types and classes

Dan Stromberg - OAC-DCS (strombrg@hydra.acs.uci.edu)
Mon, 13 Sep 93 08:24:54 -0700

It would seem one way of determining if a failure to execute a method
with a specific type is:

1) due to the lack of that method presence at all

or

2) due to the lack of an appropriate coercion

...would be to provide one or two constants with each numeric type.
"zero" and "one" would be good candidates, "one" alone being more
useful than "zero" alone.

Of course, that means adding a constant or two to a fair number of
types, but...

Given the presence of a constant "one", and operators for addition and
multiplication, it would probably be possible to provide a fairly
efficient, inheritable routine for converting ascii to a new numeric
type...

In message <9309130351.AA21576@kaos.ksr.com> you write:
>> [jack]
>> def oldstyle(x):
>> if type(x) in (type(()), type([])):
>> for i in range(len(x)):
>> print i, x[i]
>> else:
>> print x
>>
>> def newstyle(x):
>> if allowed(x[0]):
>> for i in range(len(x)):
>> print i, x[i]
>> else:
>> print x
>
>Is
>
> if allowed(expression):
> block1
> else:
> block2
>
>different from (assuming 'ok' and 'dummy' are otherwise unused)
>
> ok = 1
> try:
> dummy = expression
> except (TypeError, AttributeError):
> ok = 0
>
> if ok:
> block1
> else:
> block2
>
>? I suppose you don't actually want to evaluate 'expression', though, or
>more likely specifically want _not_ to evaluate 'expression'. I'm not
>sure that's possible in general, though. For example, even if x is an
>instance of a class that supports a __sub__ method, there's no guarantee
>that, e.g.,
>
> x-1
>
>will end up invoking x.__sub__: it depends on what x.__coerce__ decides
>to do, and I doubt that's determinable, in general, without executing the
>code.
>
>I like the _idea_, because it gets directly at Guido's pragmatic "does
>the object support the operation or not?" test. I'm just dubious that it
>can be made to work unless the argument is restricted to operations on
>built-in objects (about whose behavior Python knows everything up front).
>
>> [steve]
>> >>> hasattr( 1, '__add__' )
>> >>> 0
>
>Cute! Makes sense, though, eh?
>
>Here's another one to ponder:
>
>>>> class K:
>... def __len__(self):
>... return 12
>...
>>>> temp=K(); hasattr(temp,'__len__'); len(temp)
>1
>12
>>>> temp=K; hasattr(temp,'__len__'); len(temp)
>1
>Stack backtrace (innermost last):
> File "<stdin>", line 1
>TypeError: len() of unsized object
>>>>
>
>I.e., just because something has a __len__ attribute doesn't necessarily
>mean you can apply the len function to it. Presumably Jack's
>'allowed(len(K))' would have returned 0 here.
>
>> [jaap]
>> def altstyle(x)
>> try:
>> for i in range(len(x)):
>> print i, x[i]
>> except TypeError:
>> print x
>
>I'm not clear on what Jack intended in the original example.
>
>"oldstyle" did the "for i in range ..." bit for and only for tuples and
>lists.
>
>"newstyle" did it (I think) for and only for tuples, lists, and objects
>that support __getitem__. However, it would raise an exception for
>objects that did support __getitem__ but not __len__. In any case, it
>doesn't do the same thing as "oldstyle" in all cases.
>
>The code of which I asked "does this differ from oldstyle?" has somewhat
>different behavior from both of those, and from "altstyle". altstyle
>hides what might be legitimate runtime type errors in an object's __len__
>or __getitem__ method, and raises AttributeError for objects that don't
>support __len__, or that do support a __len__ that returns a value > 0
>but don't support __getitem__.
>
>
>I don't mean to be irritatingly pedantic there <grin>; the primary real
>point is that I think the problem we're trying to _solve_ with this stuff
>is remarkably ill-defined (else at least _some_ pair of proposed
>solutions would get close to having the same behavior <wink>).
>
>
>> Here you would rely on the fact that len(x) would return TypeError on an
>> unsized object. Or, the x[i] would return TypeError on an unsubscriptable
>> object.
>
>Just noting that the absence of __getitem__ yields AttributeError instead
>of TypeError.
>
>> Either way, if Python would move towards a more pure OO paradigm, the
>> subscription would become a method and you should be able the turn the
>> allowed() into a simple check whether a method exists.
>
>See the "class K" example above for a context where this doesn't work as
>hoped. Is that the only exception? Suspect it is.
>
>instinctively-suspicious-of-"pure"-anything<wink>-ly y'rs - tim
>
>Tim Peters tim@ksr.com
>not speaking for Kendall Square Research Corp

Dan Stromberg - OAC/DCS strombrg@uci.edu