On Thu, 26 Jan 2006, Rocco Moretti wrote: >> You were better off with what you had before. Equality in this case is left >> completely open-ended, and as a result, there is no way that you can >> guarantee that "a == b" is the same as "b == a" if "a" is a "foo" and "b" >> is of unknown type. This can lead to bizarre and unpredictable behavior. > > Mind explaining that better? b == a *always* calls b.__eq__(a), if it exists. > What a.__eq__(b) is doesn't matter at that point. So you have the same > problems either way.
Right, but we don't know what "b.__eq__" does, since "b" could be anything, if it exists at all. So, it's quite possible that "a == b", since "a.__eq__" is defined and only depends on "b" having an attribute named "an_attribute", but "b == a" is: a) an error b) false, even though "a == b" is true If we control the class of "a" and the class of "b", we can ensure that the two "__eq__" methods behave identically. The problem is that, in the supposed interest of "polymorphism" we are relaxing the dependency on "a.__eq__"'s parameter so that it can be any class with "an_attribute". This implies that we would like other classes besides those we control to be able to participate in equality tests with the class of "a". However, to do this properly, we need to be able to modify *both classes*, or we will have inconsistent results depending on whether we say "a == b" or "b == a". It is reasonable to expect that these two expressions produce the same result, isn't it? > The only difference between the two is in the case where b is of an unrelated > class and b.an_attribute exists (1). In this case, the first always returns > False, and the second returns (a.an_attribute == b.an_attribute). Which you > prefer depends on how strictly you adhere to duck typing. I don't think duck typing buys you anything valuable here. The usual flexibility of duck typing is lost because of the symmetric nature of equality; all participating classes need to be involved to guarantee correctness. You *could* have "b.__eq__" just call "a.__eq__", but once again this assumes we have control over the implementation of "b". -- .:[ dave benjamin -( ramen/sp00 )- http://spoomusic.com/ ]:. "To attain knowledge, add things every day. To attain wisdom, remove things every day." - Lao Tzu -- http://mail.python.org/mailman/listinfo/python-list