From: Thomas Jollans on 7 Aug 2010 08:28 On 08/07/2010 09:44 AM, Gabriel Genellina wrote: > En Sat, 07 Aug 2010 04:04:06 -0300, Stefan Schwarzer > <sschwarzer(a)sschwarzer.net> escribi�: >> On 2010-08-07 00:28, Steven D'Aprano wrote: > >>> Actually, yes, equality is implemented with a short-cut > that checks for >>> identity first. That makes something like: >>> [...] >> >> Oops, I didn't realize that the OP had mentioned the >> identity check as an optimization in case the objects are >> the same. I thought he was confusing the operator with `is`. >> >>> s = "abc"*1000*1000*10 >>> s == s >>> >>> nice and quick, as Python can immediately recognise that a string is >>> always equal to itself without having to walk the entire string >>> comparing >>> each character with itself. >> >> Yes, that definitely makes sense. I guess I would have >> implemented it this way as well. :) > > For strings and other internal types this optimization certainly makes > sense. For user-defined types it gets in the way and prevents defining > an object such x==x is False (like NANs). > That's probably why this optimisation doesn't exist for user-defined types: Python 3.1.2 (release31-maint, Jul 8 2010, 09:18:08) [GCC 4.4.4] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> >>> class A: .... def __eq__(self, x): .... if self is x: return False .... else: return True .... >>> >>> A() == A() True >>> a = A() >>> a == a False >>>
From: Ben Finney on 7 Aug 2010 19:16 Peter Pearson <ppearson(a)nowhere.invalid> writes: > Hey, that's a cute example, but . . . what a trap! Is it possible to > document the use-the-object-not-the-string requirement loudly enough > that people won't get caught? Don't use strings for such values. The data isn't going to be used, so there's no sense using a semantically rich data type like a string. Instead, use an 'object' instance; then, the only way to get a binding that will compare equal is to use the very object itself. FORWARD = object() BACKWARD = object() -- \ “Never do anything against conscience even if the state demands | `\ it.” —Albert Einstein | _o__) | Ben Finney
From: Stefan Schwarzer on 8 Aug 2010 03:46 Hi Ben, On 2010-08-08 01:16, Ben Finney wrote: > Don't use strings for such values. The data isn't going to be used, so > there's no sense using a semantically rich data type like a string. > > Instead, use an 'object' instance; then, the only way to get a binding > that will compare equal is to use the very object itself. > > FORWARD = object() > BACKWARD = object() Yes, that's the obvious approach. :-) I had used strings in the example with the reasoning that they could be readily used in messages (from my post: "Using a string instead of an `object()` has the advantage that it makes usage in error messages easier."). For the record, another approach I've seen is something like FORWARD, BACKWARD, UNKNOWN = range(3) This has the same problem as when using strings for the constants but looking at the module contents it's a bit more obvious that these are just "magic numbers", so presumably the constant names should be used instead. Stefan
From: Albert van der Horst on 8 Aug 2010 11:12 In article <8c2uiuFg9bU1(a)mid.individual.net>, Peter Pearson <ppearson(a)nowhere.invalid> wrote: >On Fri, 06 Aug 2010 15:37:04 +0200, Stefan Schwarzer wrote: >[snip] >> I can imagine a case where you might want to compare a >> string with `is`: >> >> FORWARD = "forward" >> BACKWARD = "backward" >> >> ... >> >> def func(direction=FORWARD): >> if direction is FORWARD: >> ... >> elif direction is BACKWARD: >> ... >> else: >> ... >> >> in case you expect people to specifically use the constants >> you provided in the module. Here, the fact that FORWARD >> actually is the string "forward" might be considered an >> implementation detail. Using a string instead of an >> `object()` has the advantage that it makes usage in error >> messages easier. >> >> Actually, I've never seen such a use, as far as I remember. >> What do other people here think? Is the code above, which >> compares strings with `is`, bad style, and if yes, why? How >> would you write the code instead? > >Hey, that's a cute example, but . . . what a trap! Is it >possible to document the use-the-object-not-the-string requirement >loudly enough that people won't get caught? king = "This is just a string for denoting a chess object, \ if a field contains (a reference to) king, it means the piece \ is standing on that field" Even a fresh convert from the Java language would not insert the string instead of the name of the object. (In practive you want black kings and white kings to be different objects, probably.) > >-- >To email me, substitute nowhere->spamcop, invalid->net. -- -- Albert van der Horst, UTRECHT,THE NETHERLANDS Economic growth -- being exponential -- ultimately falters. albert(a)spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
From: Bruno Desthuilliers on 9 Aug 2010 05:04
Gregory Ewing a écrit : > Ethan Furman wrote: > >> Instead of using 'is' use '=='. Maybe not as cute, but definitely >> more robust! > > It's also just as efficient if you use strings that > resemble identifiers, because they will be interned, Remember : this IS an implementation detail. |