Use Python to add multiple colors to a NURBS curve
I figured out a way to do it.

I created a script that first remembers all the locations of the control points of the NURBS curve (each of which has a color associated with it in a separate variable).  Then I converted the curve to a mesh.

Next, for each vertex of the mesh, I loop through all the original NURBS control points, see which one is closest, and then color the vertex of the mesh with the corresponding color.

Here is the result:



It's not perfect, it would be better if the colors slowly blended into each other, but if you have many control points, it might be OK.

I'll include the script I used in case anyone finds it useful:

import bpy
from mathutils import Vector
import copy


def color_nurbs_curve(nurbs_obj, color_list):
    """Converts the NURBS curve which should already have a bevel object so it has some width.

    color_list should be a list of colors each of which is a 3 element list with [R,G,B]."""

    nurbs_coords = copy.deepcopy( [ nurbs_obj.data.splines[0].points[i].co for i in range(len(nurbs_obj.data.splines[0].points)) ] )

    #Error checking
    if len(nurbs_coords) != len(color_list):
        raise RuntimeError('The color list must have a number of colors equal to the number of control points of your bezier curve')
    if nurbs_obj.data.bevel_object == None:
        raise RuntimeError('Your NURBS curve must have a bevel object')

    scn = bpy.context.scene




    #Convert to mesh
    scn.objects.active = nurbs_obj
    nurbs_obj.select = True
    bpy.ops.object.convert( target='MESH' )
    #sometimes this conversion results in a bunch of doubles, so I remove the doubles
    remove_doubles(nurbs_obj)

    mesh = nurbs_obj.data 

    if len(mesh.vertex_colors) == 0:
        bpy.ops.mesh.vertex_color_add()

    nurbs_obj.active_material = bpy.data.materials.new('material')
    nurbs_obj.active_material.use_vertex_color_paint = True


    print("test",nurbs_coords[1])

    #loop through each vertex
    num_verts = len(mesh.vertices)
    for vert_i in range(num_verts):

        #record shortest separation. -99 signals unset.
        shortest_sep = -99

        #loop through all the original bezier points to see 
        #which one is closest and then color it with the corresponding color
        count=0
        for b_point in nurbs_coords:

            b_point.resize_3d()
            temp_sep = (mesh.vertices[vert_i].co -  b_point).length

            if temp_sep &lt; shortest_sep or shortest_sep == -99:
                shortest_sep = temp_sep
                color = color_list[count]

            count += 1

        color_vertex( nurbs_obj, vert_i, color )
        print( "Finished vertex: " + str(vert_i) + "/" + str(num_verts) )





def color_vertex(obj, vert, color=[1,0,0]):
    """
    Paints a single vertex

    """
    mesh = obj.data 
    scn = bpy.context.scene

    #check if our mesh already has Vertex Colors, and if not add some... (first we need to make sure it's the active object)
    scn.objects.active = obj
    obj.select = True
    if len(mesh.vertex_colors) == 0:
        bpy.ops.mesh.vertex_color_add()

    i=0
    for poly in mesh.polygons:
        for vert_side in poly.loop_indices:
            global_vert_num = poly.vertices[vert_side-min(poly.loop_indices)] 
            if vert == global_vert_num:
                mesh.vertex_colors[0].data[i].color = color

            i += 1

def remove_doubles(obj):
    """ Removes doubles using default settings"""
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_all(action='TOGGLE') #I believe objects are created with the vertices all not selected
    bpy.ops.mesh.remove_doubles()
    bpy.ops.object.mode_set(mode='OBJECT')



##Example Usage    
##nurbs_obj = bpy.data.objects['NurbsCurve']
##color_list = [  [1.0, 0.0, 0.0], [1.0, 0.25, 0.0], [1.0, 0.5, 0.0], [0.5, 0.0, 0.0], [0.0, 0.75, 0.0], [0.0, 1.0, 0.0], [0.5, 0.5, 0.5], [0.75, 0.15, 0.9]   ]
##color_nurbs_curve(nurbs_obj, color_list)