def read_slice(self, firstrow, lastrow, step=<NUM_LIT:1>, **keys):
if self._info['<STR_LIT>'] == ASCII_TBL:<EOL><INDENT>rows = numpy.arange(firstrow, lastrow, step, dtype='<STR_LIT>')<EOL>keys['<STR_LIT>'] = rows<EOL>return self.read_ascii(**keys)<EOL><DEDENT>step = keys.get('<STR_LIT>', <NUM_LIT:1>)<EOL>if self._info['<STR_LIT>'] == IMAGE_HDU:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>maxrow = self._info['<STR_LIT>']<EOL>if firstrow < <NUM_LIT:0> or lastrow > maxrow:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>" % (<NUM_LIT:0>, maxrow))<EOL><DEDENT>dtype, offsets, isvar = self.get_rec_dtype(**keys)<EOL>w, = numpy.where(isvar == True)  <EOL>if w.size > <NUM_LIT:0>:<EOL><INDENT>vstorage = keys.get('<STR_LIT>', self._vstorage)<EOL>rows = numpy.arange(firstrow, lastrow, step, dtype='<STR_LIT>')<EOL>colnums = self._extract_colnums()<EOL>array = self._read_rec_with_var(<EOL>colnums, rows, dtype, offsets, isvar, vstorage)<EOL><DEDENT>else:<EOL><INDENT>if step != <NUM_LIT:1>:<EOL><INDENT>rows = numpy.arange(firstrow, lastrow, step, dtype='<STR_LIT>')<EOL>array = self.read(rows=rows)<EOL><DEDENT>else:<EOL><INDENT>nrows = lastrow - firstrow<EOL>array = numpy.zeros(nrows, dtype=dtype)<EOL>self._FITS.read_as_rec(self._ext+<NUM_LIT:1>, firstrow+<NUM_LIT:1>, lastrow, array)<EOL>array = self._maybe_decode_fits_ascii_strings_to_unicode_py3(<EOL>array)<EOL>for colnum, name in enumerate(array.dtype.names):<EOL><INDENT>self._rescale_and_convert_field_inplace(<EOL>array,<EOL>name,<EOL>self._info['<STR_LIT>'][colnum]['<STR_LIT>'],<EOL>self._info['<STR_LIT>'][colnum]['<STR_LIT>'])<EOL><DEDENT><DEDENT><DEDENT>lower = keys.get('<STR_LIT>', False)<EOL>upper = keys.get('<STR_LIT>', False)<EOL>if self.lower or lower:<EOL><INDENT>_names_to_lower_if_recarray(array)<EOL><DEDENT>elif self.upper or upper:<EOL><INDENT>_names_to_upper_if_recarray(array)<EOL><DEDENT>self._maybe_trim_strings(array, **keys)<EOL>return array<EOL>
Read the specified row slice from a table.

Read all rows between firstrow and lastrow (non-inclusive, as per
python slice notation).  Note you must use slice notation for
images, e.g. f[ext][20:30, 40:50]

parameters
----------
firstrow: integer
    The first row to read
lastrow: integer
    The last row to read, non-inclusive.  This follows the python list
    slice convention that one does not include the last element.
step: integer, optional
    Step between rows, default 1. e.g., if step is 2, skip every other
    row.
vstorage: string, optional
    Over-ride the default method to store variable length columns.  Can
    be 'fixed' or 'object'.  See docs on fitsio.FITS for details.
lower: bool, optional
    If True, force all columns names to lower case in output. Will over
    ride the lower= keyword from construction.
upper: bool, optional
    If True, force all columns names to upper case in output. Will over
    ride the lower= keyword from construction.