Driver action animates in viewport but not in Eevee or Cycles
I believe I have at least part of the answer to this failure:
I will attach a demo file with three scenes, each with only one procedure changed:
Scene 1 shows the failure to animate the cube's rotation as a function of its X location.  First, run the animation in the viewport and see that it is OK.  Then choose Render Animation from the Render menu - either Eevee of Cycles - and see that it will animate the cube's position but not the driver action of rotation.
Scene 2 shows only one change: I changed the variable's Space parameter from World Space to Transform Space.  Now you can see the animation also roll the cube.
Scene 3 shows the variable removed and the scripted expression modified to use Self.  Note that the expression must be a proper instance variable hierarchy:
self.location.x
Here, also, you can see the animation roll the cube.

So, what does all this mean?  I have only a rough guess:
This animation requires that the animated cube have its world-location updated in the world matrix needed for animation.  The viewport animation necessarily needs its world matrix updated every change no matter what, but the animation matrix is time-intensive and something called a dependency tree is used to update only those world matrices that have changed from the last scene.
In the case of the first, failing, scene, the world matrix entry for the cube only gets updated in its animation matrix position.  The variable refers to the same cube, but the world location of the cube hasn't changed; it's still right where it was created - at 0,0,0.  Therefore, the rotation of the cube doesn't get updated since the "location" of the cube in the world hasn't changed.
Now, in the second scene, the variable X Location is gotten not from the world location but from the transform matrix location, and that has changed as a result of the F-curve of the animation.  Now the cube rotation is part of the dependency tree and gets updated for the animation.  (Remember: I think the viewport representation simply gets updated any time anything at all changes.  The viewport is not time-critical.)
In the third scene, I eliminate the external variable altogether.  Here, using self actually passes the information from the instance of the object along to the tree and says, "update me, I'm being changed."

This, however, does not yet fix my original problem of getting this update to happen for my instantiated WheelDriver class objects to get updated in the animation procedure and not just in the viewport procedure.

More later ...
  

Equipment: Blender 2.82a, Dell G7 with NVIDIA GTX 1660 Ti, 16G Ram, Bowmore - 12 yrs old.