@taldcroft: Well yes, topcat does subscribe to `table.load.fits` as well as `table.load.votable`, partly for historical reasons.  Implementing `table.load.csv` et al. would be a one-liner, but I restrained myself for the interoperability reasons alluded to above, though if I really had the courage of my convictions I should revoke the FITS one too.

But the point here is really that the SAMP philosophy discourages you from thinking about writing code that sends a table to topcat or an image to ds9.  Instead you should just think "send a table" or "send an image", and then whatever's out there that receives tables/images can pick it up.  You might write your code with topcat in mind,  but the person who runs it later might have a different preferred general table viewer application, or might want to pick up the table to do something other than view it in a general purpose table viewer (maybe just count the rows) - the sending code doesn't have to change or know the difference.  I think that approach has a lot of value for people writing general purpose applications.  But it's arguably true that your typical astropy user may be more likely to be knocking up something for their own short term use where they know they've got topcat and ds9 running and they want to talk to them.

Regarding the string format for VOTable: TABLEDATA-serialized numeric values are described in section 6 of the [VOTable standard](http://www.ivoa.net/documents/VOTable/20130920/REC-VOTable-1.3-20130920.html#ToC43).  I don't know enough python to comment on how best to achieve that, though `repr` sounds like a good bet.  But as I say, using the `BINARY` VOTable serialization format instead is another option - it preserves precision, and may be more compact, though it is base64-encoded (in the VOTable, not the SAMP message) so you lose a factor of 4/3.