What is the proper way to test the identity of two objects?

Usually I do this:

if ob1 == ob2:

Or if the references have become outdated, it may be safer to hold onto names and see if they still exist:

objects = bpy.data.objects
ob_a = objects.get(name_a)
if ob_a is not None:
    ob_b = objects.get(name_b)
    if ob_a == ob_b:
        # found a match!

In Python, you're taught that equality is not the same as identity. Theoretically, there can be two indistinguishable Blender objects. So what I'd really like to do is test identity:

if ob1 is ob2:

However, in the Blender console:

C.object is C.object

returns False! Why is this so, and what is the recommended way for determining the identity of two objects?

  • $\begingroup$ What do you mean by "the pointers have become outdated"? Python doesn't have pointers. $\endgroup$
    – CharlesL
    Commented Jan 3, 2014 at 0:27
  • 1
    $\begingroup$ Well, it actually kind of does, but I changed the wording to "references", since that's usually what they are called in Python instead of "pointers". $\endgroup$
    – supergra
    Commented Jan 3, 2014 at 0:31
  • $\begingroup$ There is a distinction between the two, of course, but from a high-level they work the same way. In Blender, the reference to an object can become invalid. For example, if you delete the object, while holding on to a reference to it. $\endgroup$
    – supergra
    Commented Jan 3, 2014 at 0:37
  • $\begingroup$ If the reference is out-dated its not safer to do if ob1.name == ob2.name, since this is reading from the reference (rather then just comparing it). $\endgroup$
    – ideasman42
    Commented Jan 3, 2014 at 1:28
  • 1
    $\begingroup$ @CharlesL Python doesn't have native Pointers (unless you count ctypes), but internally (in the Py-C-API), pointers are used, ideally script authors wouldn't have to care about this but there are exceptions to that. $\endgroup$
    – ideasman42
    Commented Jan 3, 2014 at 1:32

2 Answers 2


In short, for the bpy api use ==, instead of is or comparing the name (which is error prone).

Blender data-blocks * happen not to be Python objects, that is to say, when Blender creates a mesh for example, there exists no Python object for it, until a script asks for one, The way the Python API works, each data-block is a reference to Blender data. therefor id(bpy.context.object) == id(bpy.context.object) won't be equal since each time a new python-object is created.


This is not the case for all areas of Blender, The game-engine (bge) and the bmesh api's can use identity for comparisons.


If you do want a unique id() for a data-block you can do:
ob1.as_pointer() == ob2.as_pointer(), this is specific to the bpy api.

* In Blender data-block is a general term for a scene, group, mesh, image, material, texture... etc, (avoiding the term object since its confusing in this context)

  • $\begingroup$ I see in the API that as_pointer() returns an integer. So this can be used to compare datablocks even after they are deleted? (Not saying that would be a good idea...) $\endgroup$
    – supergra
    Commented Jan 3, 2014 at 1:55
  • $\begingroup$ Furthermore, it looks like you could then be more Pythonic and write: ob1.as_pointer() is ob2.as_pointer(), recovering the is syntax. $\endgroup$
    – supergra
    Commented Jan 3, 2014 at 1:55
  • $\begingroup$ And is it possible that a datablock will maintain its content, but have its memory location shifted? (In other words can the value returned by as_pointer() become stale, despite the datablock still existing?) $\endgroup$
    – supergra
    Commented Jan 3, 2014 at 2:07
  • $\begingroup$ Strictly speaking you shouldn't use as_pointer() on a data-block that's been freed, Since its possible a newly allocated object has the same address, In general its best do avoid holding references to objects for extended periods where you aren't sure if they are removed or not on future access. $\endgroup$
    – ideasman42
    Commented Jan 3, 2014 at 6:45
  • $\begingroup$ Also note that if an object is deleted and then 'UNDO'ne, as_pointer() method will return a different address than the one prior to deleting. $\endgroup$
    – Justas
    Commented Jul 24, 2019 at 22:54

In (C)Python, the is operator is based on id(), which returns the memory address of a python object. For some reason, calling id(bpy.context.active_object) consecutively does not return the same value. I assume this is an implementation detail(or bug) of the Blender Python API.

Without id() working as expected, you can't use is for comparison. But == works just fine from my quick testing.

You are right that using obj.name to compare object is not ideal. Use BlenderObject == BlenderObject when possible.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .