0

Just stumble upon this, consider following code:

class A(object):
    pass


class B(object):
    pass

a = A()
b = B()

print a > b  # False

The doc states:

If no __cmp__(), __eq__() or __ne__() operation is defined, class instances are compared by object identity (“address”).

In above code the address of a and b were at runtime:

id(a)  # >>> 4499550864
id(b)  # >>> 4499682960

So it makes sense why the a > b yields False, as address of a is not greater than address of b?(Is this what's happening?) If we consider above conclusion, just changing the position of instance creation in above code still yields a > b as False:

b = B()
a = A()
assert id(a) > id(b)  # doesn't raises assertion error
print a > b  # >>> False (why still False??)

Why?? isn't address of a is now bigger than address of b? (I guess it is as assertion error was not raised.)

Aamir Rind
  • 38,793
  • 23
  • 126
  • 164
  • I don't know; is it? Surely you can look and see. – kindall Jul 17 '17 at 22:05
  • @kindall What you mean by `I don't know; is it?` are you asking for truthfulness of statement `isn't address of a is now bigger than address of b? (surely it is)` in second case? – Aamir Rind Jul 17 '17 at 22:08
  • 1
    If your assumption was correct, all Python programs would crash after a while as there would be no new, higher memory addresses for new objects. In reality, Python reallocates your memory all the time and an object created at later time does not necessarily have a higher address than the objects that were created before it. – zwer Jul 17 '17 at 22:09
  • @zwer I understand this concept, but i had an assert statement to make sure id of `a` was indeed greater than id of `b` for second case. http://dpaste.com/1KS6333 – Aamir Rind Jul 17 '17 at 22:12
  • Ideally.. the hash function determines the address of the object and the document states that "x.__hash__() returns a result derived from id(x)." However, I am getting different values for hash and id.. – user1211 Jul 17 '17 at 22:15
  • @AamirAdnan - That's a whole different issue, I was addressing only the wrong assumption that will always fulfill `id(new_object) > id(old_object)`. When it comes to comparison, Python (at least CPython) uses `hash()` and not `id()` - that's why it can natively compare integers at no expense and no matter where they are in the memory. – zwer Jul 17 '17 at 22:19
  • @zwer Thanks I have removed my statement "surely it is". Is this still a duplicate as the linked question does not answer this behaviour? – Aamir Rind Jul 17 '17 at 22:24
  • Python compares memory addresses only if two objects have the same type. If the types are different, the names of types are compared. Yes, it's still a duplicate. – vaultah Jul 17 '17 at 22:25
  • _"Objects of different types, except different numeric types and different string types, never compare equal; such objects are **ordered consistently but arbitrarily** (so that sorting a heterogeneous array yields a consistent result)"_, see https://docs.python.org/2/library/stdtypes.html I think _arbitrarily_ is the keyword to what you observe. – AGN Gazer Jul 17 '17 at 22:30
  • @vaultah Thanks, that makes sense now. Found in doc *User-defined classes have `__cmp__()` and `__hash__()` methods by default; with them, all objects compare unequal (except with themselves) and `x.__hash__()` returns a result derived from `id(x)`.* – Aamir Rind Jul 17 '17 at 22:30

0 Answers0