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)