Unnamed Python objects have the same id
From the doc of id(object)
:
Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.
Since the two ranges inside the id()
calls have non-overlapping lifetimes, their id values may be the same.
The two ranges assigned to variables have overlapping lifetimes so they must have different id values.
Edit:
A look into the C sources shows us builtin_id
:
builtin_id(PyObject *self, PyObject *v)
{
return PyLong_FromVoidPtr(v);
}
and for PyLong_FromVoidPtr
.
PyLong_FromVoidPtr(void *p)
{
#if SIZEOF_VOID_P <= SIZEOF_LONG
return PyLong_FromUnsignedLong((unsigned long)(Py_uintptr_t)p);
#else
#ifndef HAVE_LONG_LONG
# error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long"
#endif
#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
# error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
#endif
return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)(Py_uintptr_t)p);
#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
}
So the ID is a memory address.
Horrible redraw performance of the DataGridView on one of my two screens
You just need to make a custom class based off of DataGridView so you can enable its DoubleBuffering. That's it!
class CustomDataGridView: DataGridView
{
public CustomDataGridView()
{
DoubleBuffered = true;
}
}
As long as all of my instances of the grid are using this custom version, all is well. If I ever run into a situation caused by this where I'm not able to use the subclass solution (if I don't have the code), I suppose I could try to inject that control onto the form :) (although I'll be more likely to try using reflection to force the DoubleBuffered property on from the outside to once again avoid the dependency).
It is sad that such a trivially simple thing ate up so much of my time...
Note: Making the answer an answer so the question can be marked as answered
Why do different methods of same object have the same 'id'?
The same memory location is being used by Python for methods a.f
and a.g
, which are **two objects with non-overlapping lifetimes*, so id
returns same identity for both of them. See more detailed explanations below.
From the documentation for the is operator:
The operators is and is not test for object identity: x is y is true
if and only if x and y are the same object.
From the documentation for the is id
Return the “identity” of an object. This is an integer (or long
integer) which is guaranteed to be unique and constant for this object
during its lifetime. Two objects with non-overlapping lifetimes may
have the same id() value.
Explanations:
Whenever you look up a method via class.name
or instance.name
, the method object is created a-new. Python uses the descriptor protocol to wrap the function in a method object each time.
So, when you look up id(a.f)
or id(a.g)
, a new method object is created.
- When you grubbing id of
a.f
, a copy of it is created in memory. This memory location is returned byid
. - Since there are no references to the newly created method, it reclaimed by the GC (now memory address is available again).
- After you getting id of
a.g
, a copy of it is created at the same memory address, which you retrieve usingid
again. - You've got truthy id's comparison.
Good luck!
Python: different objects get the same id
This is an interesting question, but it's well explained in wtfpython.
When a and b are set to "hello" in the same line, the Python interpreter creates a new object, then references the second variable at the same time. If you do it on separate lines, it doesn't "know" that there's already
hello
as an object (because "hello" is not implicitly interned as per the facts mentioned above). It's a compiler optimization and specifically applies to the interactive environment.
One thing that differs is that in IPython, things might be a bit different from direct Python REPL, so this explains the difference in id
in your first two inputs.
The 'is' operator is not working on objects with the same identity
After id(300)
is executed, no more references to 300
exist, so the id is freed. When you execute id(6)
, it gets that same chunk of memory and stores 6 instead. When you do -300 is 6
, -300
and 6
are both referenced at the same time, so they won't have the same address anymore.
If you keep references to both -300
and 6
, this happens:
>>> a, b = -300, 6
>>> id(a)
some number
>>> id(b)
some different number; 6 is still in the other memory address.
Note: In CPython, numbers from -5 to 256 (I think) are cached, and will always have the same address, so this will not happen.
How does `is` work in the case of ephemeral objects sharing the same memory address?
Two unmutable objects, sharing the same address, would, as you are concerned, be indistinguishable from each other.
The thing is that when you do a[:] is a[:]
both objetcts are not at the same address - in order for the identity operator is
to compare both objects, both operands have to exist - so, there is still a reference to the object at the left hand side when the native code for is
is actually run.
On the other hand, when you do id(a[:]),id(a[:])
the object inside the parentheses on the first call is left without any references as soon as the id
function call is done, and is destroyed, freeing the memory block to be used by the second a[:]
.
Why does `is` return False even though id's are identical?
Just re-entering my comment as "an answer":
Simply because the same memory is reused for the objects: in the last two statements, the lifetimes of the objects whose id's you're obtaining do not overlap, so Python is free to (re)use the same memory for them.
id() vs `is` operator. Is it safe to compare `id`s? Does the same `id` mean the same object?
According to the id()
documentation, an id
is only guaranteed to be unique
- for the lifetime of the specific object, and
- within a specific interpreter instance
As such, comparing id
s is not safe unless you also somehow ensure that both objects whose id
s are taken are still alive at the time of comparison (and are associated with the same Python interpreter instance, but you need to really try to make that become false).
Which is exactly what is
does -- which makes comparing id
s redundant. If you cannot use the is
syntax for whatever reason, there's always operator.is_
.
Now, whether an object is still alive at the time of comparison is not always obvious (and sometimes is grossly non-obvious):
Accessing some attributes (e.g. bound methods of an object) creates a new object each time. So, the result's
id
may or may not be the same on each attribute access.Example:
>>> class C(object): pass
>>> c=C()
>>> c.a=1
>>> c.a is c.a
True # same object each time
>>> c.__init__ is c.__init__
False # a different object each time
# The above two are not the only possible cases.
# An attribute may be implemented to sometimes return the same object
# and sometimes a different one:
@property
def page(self):
if check_for_new_version():
self._page=get_new_version()
return self._pageIf an object is created as a result of calculating an expression and not saved anywhere, it's immediately discarded,1 and any object created after that can take up its
id
.This is even true within the same code line. E.g. the result of
id(create_foo()) == id(create_bar())
is undefined.Example:
>>> id([]) #the list object is discarded when id() returns
39733320L
>>> id([]) #a new, unrelated object is created (and discarded, too)
39733320L #its id can happen to be the same
>>> id([[]])
39733640L #or not
>>> id([])
39733640L #you never really know
Due to the above safety requirements when comparing id
s, saving an id
instead of the object is not very useful because you have to save a reference to the object itself anyway -- to ensure that it stays alive. Neither is there any performance gain: is
implementation is as simple as comparing pointers.
Finally, as an internal optimization (and implementation detail, so this may differ between implementations and releases), CPython reuses some often-used simple objects of immutable types. As of this writing, that includes small integers and some strings. So even if you got them from different places, their id
s might coincide.
This does not (technically) violate the above id()
documentation's uniqueness promises: the reused object stays alive through all the reuses.
This is also not a big deal because whether two variables point to the same object or not is only practical to know if the object is mutable: if two variables point to the same mutable object, mutating one will (unexpectedly) change the other, too. Immutable types don't have that problem, so for them, it doesn't matter if two variables point to two identical objects or to the same one.
1Sometimes, this is called "unnamed expression".
Related Topics
What Version of Visual Studio Is Python on My Computer Compiled With
How to Plot Nan Values as a Special Color with Imshow in Matplotlib
List() Uses Slightly More Memory Than List Comprehension
What Is the Fastest Way to Parse Large Xml Docs in Python
Convert Floating Point Number to a Certain Precision, and Then Copy to String
Getting the Docstring from a Function
Zlib.Error: Error -3 While Decompressing: Incorrect Header Check
Find the Most Frequent Number in a Numpy Array
Configuring Spark to Work with Jupyter Notebook and Anaconda
Chain-Calling Parent Initialisers in Python
Count Number of Non-Nan Entries in Each Column of Spark Dataframe with Pyspark
How to Convert an Array of Strings to an Array of Floats in Numpy
Importerror: No Module Named Crypto.Cipher
Valueerror: Numpy.Dtype Has the Wrong Size, Try Recompiling
Python Pandas: How to Specify Data Types When Reading an Excel File