2
$\begingroup$

In the first example, a is b returns True as it should. In the second, it is False. (assume Blender is just opened and the default cube is present and selected). I thought I was starting to understand until I got False. This is copied form the Python console.

>>> a = [1, 2, 3]
>>> b = a
>>> a == b
True

>>> a is b
True

>>> a = bpy.context.active_object.data
>>> b = bpy.data.meshes[bpy.context.active_object.name]
>>> a
bpy.data.meshes['Cube']

>>> b
bpy.data.meshes['Cube']

>>> type(a)
<class 'bpy_types.Mesh'>

>>> type(b)
<class 'bpy_types.Mesh'>

>>> a == b
True

>>> a is b
False   # WHY?

Another example based on @ideasman42 explanation...

>>> a = bpy.context.object
>>> b = bpy.context.object
>>> a is b
False
$\endgroup$
  • $\begingroup$ Note, in this case a=7; b=7'; a is b is incidental, you cant rely on this behavior. Testing with 1000 here fails. - Edited question with an example that will work reliably. $\endgroup$ – ideasman42 May 31 '15 at 11:30
  • $\begingroup$ The second example is incorrect, it assumes the object name matches the mesh name. $\endgroup$ – ideasman42 May 31 '15 at 11:41
  • $\begingroup$ related pycon 2015 talk: youtube.com/watch?v=sH4XF6pKKmk $\endgroup$ – zeffii May 31 '15 at 11:44
2
$\begingroup$

Each time you access object.data it will return a new instance, however this is a very small data type to access the real mesh data stored in Blender.

Equality works as expected (and they have the same __hash__), so you can put them into dict/set types. You just can't rely on identity. (As with any 2 strings with the same content).

$\endgroup$
  • $\begingroup$ Each time bpy.data is accessed, the data is instanciated again? Really? So if I have 1000 mesh objects, and I operate on all of them in every frame... YIKES!!! Are they garbage collected efficiently? How can I simply get a reference to the data, not another instance? $\endgroup$ – uhoh May 31 '15 at 11:07
  • $\begingroup$ @uhoh, you can test it, but as it happens bpy.data no, elaborated answer since object.data will. Note that this also happens when you do operations such as num + 1, Python's GC is optimized for creating and throwing away many small objects. In this case a Mesh isn't taking significantly difference amount of memory to a number. $\endgroup$ – ideasman42 May 31 '15 at 11:16
  • $\begingroup$ So @ideasman42 are you saying that it is a reference that it is instantiated, not the whole mesh, vertices, normals, etc? Is this explained clearly somewhere? $\endgroup$ – uhoh May 31 '15 at 11:20
  • $\begingroup$ It could be explained more clearly, but see: blender.org/api/blender_python_api_2_74_release/… $\endgroup$ – ideasman42 May 31 '15 at 11:22
2
$\begingroup$

In this case I am going to add an answer to my question - with my own choice of wording that makes it clear to me. It may help others in my situation.

The "I" in API stands for interface. Objects, data, etc. are really "in C" (so to speak) at all times. bpy.context.objects, bpy.data.meshes are not THE objects or meshes.

These are just "temporary conduits" that allow information to travel between your script and the "real" Blender program. They are instantiated each time they are used. This is why (for example):

>>> bpy.context.object is bpy.context.object
False

The wording in this subsection of the API reference helped.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.