docs: def select(self, fields, **exprs):
          """
          Create a new table containing a subset of attributes, with optionally 
          newly-added fields computed from each rec in the original table.
  
          @param fields: list of strings, or single space-delimited string, listing attribute name to be included in the
          output
          @type fields: list, or space-delimited string
          @param exprs: one or more named callable arguments, to compute additional fields using the given function
          @type exprs: C{name=callable}, callable takes the record as an argument, and returns the new attribute value
          If a string is passed as a callable, this string will be used using string formatting, given the record
          as a source of interpolation values.  For instance, C{fullName = '%(lastName)s, %(firstName)s'}
          
          """
          fields = self._parse_fields_string(fields)
  
          def _make_string_callable(expr):
              if isinstance(expr, basestring):
                  return lambda r: expr % r
              else:
                  return expr
  
          exprs = dict((k, _make_string_callable(v)) for k, v in exprs.items())
              
          raw_tuples = []
          for ob in self.obs:
              attrvalues = tuple(getattr(ob, fieldname, None) for fieldname in fields)
              if exprs:
                  attrvalues += tuple(expr(ob) for expr in exprs.values())
              raw_tuples.append(attrvalues)
          
          all_names = tuple(fields) + tuple(exprs.keys())
          ret = Table()
          ret._indexes.update(dict((k, v.copy_template()) for k, v in self._indexes.items() if k in all_names))
          return ret().insert_many(DataObject(**dict(zip(all_names, outtuple))) for outtuple in raw_tuples)