In python console if I

def selected_curves():
    print("active objects:")
    crvs = []
    for obj in bpy.data.objects:
        if obj.select:
            print( obj.name)
            print( obj.type)
            if obj.type == 'CURVE':
                print('is a curve' )

then call


I get:

active objects:
NurbsPath.000 CURVE is a curve NurbsPath.001 CURVE is a curve NurbsPath.003 CURVE is a curve

Then say try an lookup above in bpy.data.curves say:


Traceback (most recent call last): File "", line 1, in KeyError: 'bpy_prop_collection[key]: key "NurbsPath.000" not found'









as does




Why is object name NurbsPath, but curve name NurbsPath.001. Is there some logic to this?

  • $\begingroup$ >>> bpy.data.objects['NurbsPath.001'] bpy.data.objects['NurbsPath.001'] >>> bpy.data.objects['NurbsPath'] Traceback (most recent call last): File "<blender_console>", line 1, in <module> KeyError: 'bpy_prop_collection[key]: key "NurbsPath" not found' >>> bpy.data.curves['NurbsPath'] bpy.data.curves['NurbsPath'] >>> bpy.data.curves['NurbsPath.001'] bpy.data.curves['NurbsPath.001'] $\endgroup$
    – bitminer
    Commented Mar 21, 2018 at 1:51

2 Answers 2


Some blender basics.

bpy.data.objects is a collection of objects of type bpy.types.Object, as is context.selected_objects and context.scene.objects. The properties and methods of bpy.types.Object are available to all objects of any type.

Each object has a data part. When an object is created its type is set according to its data. This cannot be changed, eg trying to give a 'CURVE' type object a 'MESH type data will result in an error.

Each object has only one data member.

>>> for ob in C.selected_objects:
...     ob.name, ob.type, ob.data, type(ob.data)
('Empty', 'EMPTY', None, <class 'NoneType'>)
('BezierCurve', 'CURVE', bpy.data.curves['BezierCurve'], <class 'bpy.types.Curve'>)
('Cube', 'MESH', bpy.data.meshes['Cube'], <class 'bpy_types.Mesh'>)

for example the curve type object above has one data member of type bpy.types.Curve. All curve type objects in the file will be in the bpy.data.curves collection. The curve object is not equivalent to the curve data object.

>>> D.objects['BezierCurve'] is D.curves['BezierCurve']

but rather the data part of the object.

>>> D.objects['BezierCurve'].data is D.curves['BezierCurve']

Can set the data to any other data of the same type.

>>> C.object.data

>>> C.object.data = D.curves['BezierCurve.001']
>>> C.object.data

Each data type, can be used by none or many objects. There is no direct reference from a data object to its object. To find all the objects that use the "BezierCurve" data in a scene would use something like

>>> [o for o in C.scene.objects if o.data is D.curves['BezierCurve']]
  • $\begingroup$ I guess the real question here is how do I go from bpy.data.curves to bpy.data.objects and vise-a-versa. Say given a curve how to find it's obj? ... and given a obj it is obj.data correct? $\endgroup$
    – bitminer
    Commented Mar 21, 2018 at 15:41
  • $\begingroup$ @bitminer (apologies missed this comment) Yes: Finding the data given the obj is simple it's obj.data. The last line above shows how to find obj(s) in scene given data. $\endgroup$
    – batFINGER
    Commented Mar 21, 2018 at 19:18

Objects are an invisible shoebox that fits around your curve. It's the pivot point between the global space and your curve. It's not the curve. Inside most objects, there's data. That means, a data block is linked with the object, in this case curve datablocks.

That means curve datablocks can be used by several objects and they'll look identical.

In your first code you iterate through objects, in the second you try to access curves with the names that you've found in the objects. That can only work accidentally because the names don't have to be the same. But they could be.

That's the confusing part, I guess. The object 'BezierCircle' and the curve datablock 'BezierCircle' can have the same name while not necessarily having any connection except their spelling.

import bpy

curve_list = [] # list to collect curveblock names
print("\nYour object data:")
for ob in bpy.data.objects: # iterate through all objects
    if ob.type == "CURVE": # if it's an object holding a curve
        print("Obname: {:17}, Obtype: {}, Linked datablock: {}".format(ob.name, ob.type, ob.data.name))             
        curve_list.append(ob.data.name) # include the name in the list

print("\nyour curve datablocks:") 
for cu in curve_list: # go through the list of curve names

"Confusion" by Electric Light Orchestra


You must log in to answer this question.

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