'Extract a value from a Row
@param resource: the resource
@param row: the Row
@param field: the field
@return: field if field is not a Field/S3FieldSelector instance,
the value from the row otherwise'

@classmethod
def extract(cls, resource, row, field):

    error = (lambda fn: KeyError(('Field    not    found:    %s' % fn)))
    t = type(field)
    if isinstance(field, Field):
        colname = str(field)
        (tname, fname) = colname.split('.', 1)
    elif (t is S3FieldSelector):
        rfield = S3ResourceField(resource, field.name)
        colname = rfield.colname
        if (not colname):
            raise error(field.name)
        fname = rfield.fname
        tname = rfield.tname
    elif (t is S3ResourceField):
        colname = field.colname
        if (not colname):
            return None
        fname = field.fname
        tname = field.tname
    else:
        return field
    if (type(row) is Row):
        try:
            if (tname in row.__dict__):
                value = ogetattr(ogetattr(row, tname), fname)
            else:
                value = ogetattr(row, fname)
        except:
            try:
                value = row[colname]
            except (KeyError, AttributeError):
                raise error(colname)
    elif (fname in row):
        value = row[fname]
    elif (colname in row):
        value = row[colname]
    elif ((tname is not None) and (tname in row) and (fname in row[tname])):
        value = row[tname][fname]
    else:
        raise error(colname)
    if callable(value):
        try:
            value = value()
        except:
            (t, m) = sys.exc_info()[:2]
            current.log.error(('%s.%s:    %s' % (tname, fname, (str(m) or t.__name__))))
            value = None
    if hasattr(field, 'expr'):
        return field.expr(value)
    return value
