On Friday 21 June 2002 12:19 am, Todd Miller wrote: ... > >I'm concerned that this will also make floats acceptable as indices > >(since they have an __int__ method) and this would cause atrocities > >like > > > >print "hello"[3.5] ... > That makes sense. What if we specifically excluded Float objects from > the conversion? Are there any types that need to be excluded? If "Any type that's float-like", and that's a very hard set to pin down. Consider a user-written class that implements (e.g.) a number in decimal form (maybe BCD), carefully crafted to "look&feel just like float" except for its specifics (such as different rounding behavior). How would you tell that this class is NOT acceptable as a sequence index even though it has an __int__ method while another class with an __int__ method IS OK? It seems to me that one solution would be to add an attribute that is to be exposed by types / classes that WANT to be usable as indices in this way. If, say, the object exposes an attribute _usable_as_sequence_index, then the indexing code could proceed, otherwise, TypeError. It's quite sad that a lot of ad-hoc approaches such as this one have to be devised in each and every similar case, when PEP 246, gathering dust in the PEP repository, offers such a simple, elegant architecture for them all. Basically, PEP 246 lets you ask a "central mechanism", given an object X and a "protocol" Y, to yield a Z (where Z is X if feasible, but in many cases might be a "version of X which is Y-fied without loss of information") such that Z is "X or a version of X that satisfies protocol Y". "Adaptation" is the name commonly used for this approach (also in PEP 246). When X can't be adapted to Y, an exception gets raised. Here, indexing code could ask for an adaptation of X to the "sequence index protocol" and get either "a version of X usable as sequence index" or an exception. "A protocol" is normally a type or class, and "Z satisfies protocol Y" may then be roughly equated to "Z is an instance of Y", but the concept is more general. If Python had a formal concept of 'interface', a protocol might also be an interface -- this is apparently what's holding up PEP 246, waiting for such 'interfaces' to appear. But "a protocol" may in fact be any object at all and the concept of "satisfying" it is really a matter of convention between the code that requests adaptation and the code that _provides_ adaptation. The latter may live in X's type, or in the Y protocol, or *outside of both* and get added to the "central mechanism" dynamically -- so you get a chance to adapt two separately developed frameworks without as much blood, sweat and tears as currently needed. (The compile-time equivalent of this is in Haskell's "typeclass" mechanism, but of course Python moves it to runtime instead.) Back to your specific issue. "An integer" is too BROAD a concept. When some client-code has an object X and "wants an integer equivalent of X" it may have SEVERAL different purposes in mind. int(X) can't guess and so provides only ONE way -- for example, truncating the fractional part if X is a float. If the client-code could ask more precisely for "give me a version of X to be used as a sequence index" it would still get back either an int OR an exception, BUT, the int result would only be supplied if "it was known" that X is indeed "usable without loss of information" for the specific purpose of indexing a sequence. The "it was known" part could reside in any one of three places: a. the SequenceIndexing protocol could 'know' that e.g. every int X is OK as a sequence index, and immediately return such an X if asked for adaptation of it; b. a type could 'know' its instances are OK as sequence indices, and supply the equivalent-for-THAT-purpose int on request; c. a "third-party" adapter could know that, for this application, instances of type A are OK to use as sequence indices: the third-party adapter would be installed at application startup, get invoked upon such adaptation requests when X is an instance of type A, and provide the needed int. See PEP 246 for one possible mechanism (at Python-level) to support this, but the mechanism is of course fully negotiable. The point is that we NEED something like PEP 246 each and every time we want to perform any task of this ilk. Almost every time I see type-testing (as implicit in the idea "but do something different if X is a float", for example), I see a need for PEP 246 that stays unmet because PEP 246 is waiting... 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