I get the following:
import numpy
print id(numpy.float64(100)) == id(numpy.float64(10))
print numpy.float64(100) == numpy.float64(10)
gives:
True
False
Note that if I create the two float64 objects and then compare them then it appears to work as expected:
a = numpy.float64(10)
b = numpy.float64(100)
print a==b, id(a)==id(b)
gives:
False
False
Based on https://docs.python.org/2/reference/datamodel.html shouldn't the id of two objects always differ if their values differ? How can I get the id to match if the values are different?
Is this some sort of bug in numpy?
This looks like a quirk of memory reuse rather than a NumPy bug.
The line
id(numpy.float64(100)) == id(numpy.float64(10))
first creates a float numpy.float64(100) and then calls the id function on it. This memory is then immediately freed by Python's garbage collector because there are no more references to it. The memory slot is free to be reused by any new objects that are created.
When numpy.float64(10) is created, it occupies the same memory location, hence the memory addresses returned by id compare equal.
This chain of events is perhaps clearer when you look at the bytecode:
>>> dis.dis('id(numpy.float64(100)) == id(numpy.float64(10))')
0 LOAD_NAME 0 (id)
3 LOAD_NAME 1 (numpy)
6 LOAD_ATTR 2 (float64)
9 LOAD_CONST 0 (100)
12 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # call numpy.float64(100)
15 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # get id of object
# gc runs and frees memory occupied by numpy.float64(100)
18 LOAD_NAME 0 (id)
21 LOAD_NAME 1 (numpy)
24 LOAD_ATTR 2 (float64)
27 LOAD_CONST 1 (10)
30 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # call numpy.float64(10)
33 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # get id of object
36 COMPARE_OP 2 (==) # compare the two ids
39 RETURN_VALUE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With