Question about isinstance()

Dave Benjamin ramen at
Thu Jan 26 15:15:43 EST 2006

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 )- ]:.

       "To attain knowledge, add things every day.
        To attain wisdom, remove things every day." - Lao Tzu

More information about the Python-list mailing list