I’ve noticed that the objects in bpy.data are not static–that is, the indices which refer to them change depending on naming, or the naming of other objects of the same type. The API docs are a bit terse on the subject. I am looking for immutable objects, if they exist.
Perhaps there is more documentation which touches on this subject elsewhere.
I am not aware of any immutable data access, someone could correct me on that.
In reference to data names the API suggests creating a dictionary to store the mapping https://docs.blender.org/api/master/info_gotcha.html#data-names. Following that advice I would make a tuple/list/dictionary/object from bpy.data to store any data that should be immutable. The references in your own data structure will remain linked to the correct objects regardless of any renames or data creation that occurs…
I don’t think immutable data could work for Blender, since most of the data you work with can become invalid whenever there is an update. And I don’t mean an update in the number of objects or anything like that – I mean any depsgraph update, even if none of the objects change, nothing is added or removed. Or mode changes (edit-mode data simply does not exist in object mode, it is re-built each time you enter edit mode).
I think I need to keep rereading that document. I’ve been over it a few times (especially the part about contexts, which is pretty frustrating). It does offer some alternatives which I can try. What I’ve fallen back on is taking a survey of the things I am interested before I know something might change their bpy.data. index, and then finding them again after I’ve done what I needed to do. Which is horribly inefficient and will not scale, but it works for what I am doing now.
In Maya, if you use the internal API objects to point to data, it will be immutable so long as they aren’t changed or removed. The addition, changing, or removal of other data won’t affect those objects.
If you’re refering to the MEL API, that’s because you keep track of things by name… you can just do that in Blender, too
names = [ob.name for ob in objects] is an efficient one-liner for that. This is actually faster than:
names = 
for ob in objects:
And anyways, if you are writing code that invalidates the context, it might just be bad code. At least in most circumstances, for non-modal operators this is the case. Perhaps if I knew a little more about what you were doing I could offer specific advice.
Please also note that a name may not be unique if there is more than one .blend file loaded in a scene (in the case of e.g. linking data).
Thanks for your reply. I am referring to maya.api.OpenMaya, which is fully object oriented. Objects are inherently unique and immutable. Side note, (full) names in maya are unique as well, although mutable, which is why I don’t like to rely on them.
I am sure my blender code is bad! It would probably be better if I were able to learn how to deal with objects efficiently, which is part of what this post is about.
Sure, in the case which brought the mutable indexing of bpy.data.objects to my attention, I was importing various obj files into the scene (without knowing the names of the contents in advance), which caused the indices to get reshuffled.
I wonder if maybe it would be better to create a script that creates a new .blend file for each .obj and then links/imports from there? That way, you’d have access to the Blender data.
At any rate, you should use USD, or ABC if you can, since those importers are faster (C++ instead of Python). Also, I think USD will allow you to query info about the scene before you import it.
Could explain a little more what you mean by immutable objects and why this is desirable/useful? Wikipedia says In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created. To me, this seems backwards… in Blender’s API, everything is conceived of as modifying the data of objects, rather than running operations on objects (side effects are mostly avoided). From my experience with MEL, it seems the opposite convention is followed. Instead of object.member.property = value it is something like setattr("object.member.property", value). Is this related? Am I missing the mark? I just wonder if the paradigm in Blender’s API is more different than you expected and it is throwing you off?
Then again, I’ve never used “OpenMaya” (what a ridiculous name), so I don’t know how it compares to MEL. Well, I don’t know how much we should talk about Maya stuff, anyways. Ton recently had to remove a bunch of images from the forum because it used images of other softwares (want to avoid copyright trouble).