To debug your problem, look closely at this part of the error message:
in execute cf = camera.animation_data.action.fcurves AttributeError: 'NoneType' object has no attribute 'action'
NoneType
is telling you that one of the attributes of camera.animation_data.action.fcurves
has no value and so it can't have an attribute.
action
is telling you where Python had to stop parsing the variable. The attribute before action
is animation_data
. This tells you that camera
has an empty animation_data
attribute.
You confirmed this by running the suggested test:
if camera.animation_data is None: print('oops')
on the Python console. It printed "oops" verifying that the value of camera.animation_data
was empty.
It turned out that the reason for this is because you had set camera
incorrectly, perhaps by setting it to bpy.context.scene.camera
or bpy.data.objects["Camera"]
. That's because when you animated the focal length, (the variable is lens
, by the way) The animation data was actually attached to bpy.data.cameras["Camera"]
.
So that means that the reference you need is bpy.data.cameras["Camera"].animation_data.action.fcurves
.
This of course, is only true if there is only one camera and you haven't changed its name to something other than "Camera". In other cases, you'd have to find a different way to select the correct camera from bpy.data.cameras
.
NoneType
suggests thatcamera
isn't pointing to an actual object, or the object doesn't have animation data, because this works:>>> camera = C.scene.camera >>> camera.animation_data.action.fcurves bpy.data.actions['CameraAction'].fcurves
$\endgroup$if camera.animation_data is None: print('oops')
$\endgroup$