Counterintuitive Python behavior

Greg Weeks weeks at vitus.scs.agilent.com
Sat Apr 20 13:57:30 EDT 2002


Some comments regarding "conceptual sameness":


From: "Petr Prikryl" <Answer.via.news.please.prikryl at skil.nospam.cz>

> There are two distinct things when comparing the objects: the object
> content and the object identity.

Neither of these concepts corresponds to conceptual sameness.  I haven't
defined "conceptual sameness", but it is a natural concept:

Suppose a Bank_account type has the single attribute "balance".  Consider

    my_account = Bank_account(50)	# INITIAL BALANCE OF $50
    my_account.deposit(50)		# BALANCE IS NOW $100
    your_account = Bank_account(100)	# INITIAL BALANCE OF $100

Do we have the same bank account?  Of course not.  Adding money to your
bank account is different from adding money to my bank account.  So, in
this case, conceptual sameness corresponds to sameness of identity.  The
same goes for lists and dictionaries, for the same reasons.

On the other hand, suppose we define our own Complex number class.

    x = Complex(3,4)
    y = Complex(3,0) + Complex(0,4)

Are x and y the same?  Of course.  There is only one 3+i4.  In this case,
conceptual sameness corresponds to sameness of content.

A final example is immutable strings, which we imagine to be implemented as
a character array plus start and stop indices.  (This implementation
permits a rapid substring operation.  Note that the three attributes are
not allowed to be modified after they are initialized.)  Consider:

    s1 = String(['c', 'a', 't'], 1, 3)
    s2 = String(['a', 't', 'e'], 0, 2)

Are these the same string?  Conceptually, yes.  When you are comparing
strings in your code, it will be conceptual sameness that you are
interested in.  But neither the identity nor the content of s1 and s2 are
the same.

So, conceptual sameness corresponds sometimes to sameness of identity,
sometimes to sameness of content, and sometimes to neither.  And (I
maintain), in ordinary user code, conceptual sameness is the concept of
*identity* that is most useful.  (I stress "identity" because there are
weaker forms of comparison that are sometimes useful.  But not *as*
useful.)

So Python is missing THE single most useful comparision operator.  But
there are workarounds.  "==" means conceptual sameness for all objects
other than lists and dictionaries, provided that __cmp__ is appropriately
defined.  Furthermore, if __hash__ is appropriately defined, any object
other than a list or dictionary can be a hash key.  So, except for lists
and dictionaries, everything's fine.


From: Philip Swartzleonard <starx at pacbell.net>
> >     a eq a          # PROVIDED a HAS A VALUE
> 
> Well, if a is defined, a has a value. So this is either true or a 
> NameError (?). Or do you mean if a is None, a eq a should be false?

No.  I was perhaps overfastidiously ruling out:

    >>> a is a
    Traceback (innermost last):
      File "<stdin>", line 1, in ?
    NameError: a


Regards,
Greg




More information about the Python-list mailing list