Looping Hook Modifier Assignment
After a great deal of rearranging code and learning what doesn't work, I've finally found the solution! The key turned out to be these two lines from the answer to the related question, (Using python to create a curve and attach its endpoints with hooks to two spheres):

bpy.ops.object.mode_set(mode='EDIT')

# the mode_set() invalidated the pointers, so get fresh ones
p0 = curve.splines[0].bezier_points[0]
...


So all I needed was to add the line p = noodcurv.splines[0].bezier_points, before entering the loop. So this is the final code:

noodcurv = bpy.data.curves.new('noodcurve', type='CURVE')       #create a new curve
noodcurv.dimensions = '3D'                                      #set some settings
noodcurv.resolution_u = 2
noodcurv.bevel_object = bevob
noodcurv.use_fill_caps = True

bez = noodcurv.splines.new('BEZIER')                            #create a new spline
bez.bezier_points.add(len(coords)-1)                            #add points
p = bez.bezier_points                                           #for convenience
for k, coord in enumerate(coords):                              #set coordinates &amp; handles
    p[k].co = coord
    p[k].handle_right_type = 'VECTOR'                           #or 'AUTOMATIC', 'ALIGNED', 'VECTOR'
    p[k].handle_left_type = 'VECTOR'

noodcurvobj = bpy.data.objects.new('noodcurve', noodcurv)       #create object
modnames = ['hook.'+str(k).zfill(3) for k in range(len(coords))] #create modifier names

for k, coord in enumerate(coords):                              #create modifiers &amp; set Parent Object
    noodcurvobj.modifiers.new(modnames[k], type='HOOK')         
    noodcurvobj.modifiers[modnames[k]].object = bpy.context.scene.objects['link'+modnames[k][4:]]

scn = bpy.context.scene                                         #scene variable
scn.objects.link(noodcurvobj)                                   #link to scene &amp; activate
scn.objects.active = noodcurvobj

bpy.ops.object.mode_set(mode='EDIT')                            #change context

p = noodcurv.splines[0].bezier_points
for k in range(len(coords)):                                    #assign points to modifiers
    p[k].select_control_point = True                            #select point
    p[k].select_left_handle = True
    p[k].select_right_handle = True
    bpy.ops.object.hook_assign(modifier=modnames[k])            #assign vextex to modifier
    p[k].select_control_point = False                           #deselect point
    p[k].select_left_handle = False
    p[k].select_right_handle = False
    p[k].handle_right_type = 'FREE'                             #or 'AUTOMATIC', 'ALIGNED', 'VECTOR'
    p[k].handle_left_type = 'FREE'

bpy.ops.object.mode_set(mode='OBJECT')