List all objects in a .blend file

Hi,
i got a very simple yet tricky question: how can we list everything inside a .blend file? whether it be materials, meshes, images, shaders…etc?

From the python API i see one way would be to perform several iterations depending on the type of the object you want to list and make sure you perform an iteration through all available types. (using the bpy.data.materials, bpy.data.cameras, …etc)

But it would be nice to be able to have the option to go through all objects at once.

I tried to go through “bpy.data.objects” but, and this is the second part of the question, it doesnt apparently list everything. I have 9 different collections in my scene, and only 4 are listed. If i iterate through bpy.data.collections though, it lists all collections.

for l in bpy.data:
    if is callable(l):
        continue
    for item in l:
         print(item)

Couldn’t you just do this? (maybe need to filter out more struct data from bpy.data)

That seems very much overkill to me, because you are iterating not only through every object that you are looking for but through pretty much “anything” that bpy.data holds, including methods and functions you are not interested at all, but yeah it could work.

I guess the easiest way would be to construct myself that function with several loops. The thing is, im new to blender and i wouldnt want to miss any object.

Is everything i need to track in a blender scene contained in the “database datablocks” that we can see when trying to “link” specific pieces of another .blend file? Ive noticed you can even store scripts and text files…

Thanks in advance.

The definition of the BlendData struct is it contains all the data in a blend file… so if that’s what you want you should iterate through it all: BlendData(bpy_struct) — Blender Python API

If you only want to look at certain parts only iterate through those in the list.

As far as i understood, a blenddata struct only holds a piece of data of the blend file. Thus, you can have mutiple blenddata structs each holding specific parts of the file, like cameras, collections, etc.
Am i missing something?

On the other hand, another reason for asking this first question is that im embedding custom properties to all kinds of objects and its far easier to loop through bpy.data.objects than multiple loops in for example: bpy.data.meshes,…etc.

But now im facing the problem that i cannot access the updated value inmediately after in the same script because it is not updated. In the Blender API doc, there is a Gotcha talking about this Gotchas — Blender Python API, and im doing the proposed solution which is calling bpy.context.view_layer.update(), but seems to have no effect on bpy.data.objects when i try to access my custom property. It works though if i, in this specific case, look into bpy.data.meshes (because the custom property has been set in “Cube”)

Is it possible to have bpy.data.objects updated and retrieve the newer property right after?

Thanks in Advance

More specifically, why this happens?:
If i do:

bpy.data.meshes["Cube"]["hello"] = "goodbye"
property_value = bpy.data.objects["Cube"]["hello"]

…ERROR
this throws a KeyError exception, but if i do the opposite:

bpy.data.objects["Cube"]["hello"] ="goodbye"
property_value = bpy.data.meshes["Cube"]["hello"]

…OK!

Does this mean that in order to have all the blenddata collections updated like meshes, materiales etc… it suffices to write to the bpy.data.objects collection and all the rest are completly well updated?

Is this good practice and the way to go in order to develop in blender?

Can someone explain what is happening under the hood and the relationship between an “object” and for example a mesh, light, etc?