KirbyBase : replacing string exceptions
Brendan
brendandetracey at yahoo.com
Mon Nov 23 12:05:48 EST 2009
On Nov 23, 12:21 pm, Steve Howell <showel... at yahoo.com> wrote:
> On Nov 23, 7:22 am, Brendan <brendandetra... at yahoo.com> wrote:
>
> > In KirbyBase there is a method that uses string exceptions for
> > control, even though it has a defined exception. Is there any reason
> > the string exceptions below could not be replaced?
> > i.e. in code below replace:
> > raise "No Match"
> > with:
> > raise KBError()
> > and
> > except 'No Match':
> > with:
> > except KBError:
>
> It looks like in some cases KBError() should fall through and only 'No
> Match' was intended to be silently caught.
>
> I would consider either leaving it alone if it works, or doing more
> serious surgery on the code to simplify the control flow. The method
> is awfully long and nested.
>
>
>
> > I have pasted the relevant method and the class definition of KBError
> > below
>
> > #----------------------------------------------------------------------
> > # _getMatches
>
> > #----------------------------------------------------------------------
> > def _getMatches(self, fptr, fields, patterns, useRegExp):
> > # Initialize a list to hold all records that match the search
> > # criteria.
> > match_list = []
>
> > # If one of the fields to search on is 'recno', which is the
> > # table's primary key, then search just on that field and
> > return
> > # at most one record.
> > if 'recno' in fields:
> > return self._getMatchByRecno(fptr,patterns)
> > # Otherwise, search table, using all search fields and
> > patterns
> > # specified in arguments lists.
> > else:
> > new_patterns = []
> > fieldNrs = [self.field_names.index(x) for x in fields]
> > for fieldPos, pattern in zip(fieldNrs, patterns):
> > if self.field_types[fieldPos] == str:
> > # If useRegExp is True, compile the pattern to a
> > # regular expression object and add it to the
> > # new_patterns list. Otherwise, just add it to
> > # the new_patterns list. This will be used below
> > # when matching table records against the
> > patterns.
> > if useRegExp:
> > new_patterns.append(re.compile(pattern))
> > # the pattern can be a tuple with re flags
> > like re.I
> > else:
> > new_patterns.append(pattern)
> > elif self.field_types[fieldPos] == bool:
> > # If type is boolean, I am going to coerce it to
> > be
> > # either True or False by applying bool to it.
> > This
> > # is because it could be '' or []. Next, I am
> > going
> > # to convert it to the string representation:
> > either
> > # 'True' or 'False'. The reason I do this is
> > because
> > # that is how it is stored in each record of the
> > table
> > # and it is a lot faster to change this one value
> > from
> > # boolean to string than to change possibly
> > thousands
> > # of table values from string to boolean. And, if
> > they
> > # both are either 'True' or 'False' I can still
> > # compare them using the equality test and get the
> > same
> > # result as if they were both booleans.
> > new_patterns.append(str(bool(pattern)))
> > else:
> > # If type is int, float, date, or datetime, this
> > next
> > # bit of code will split the the comparison string
> > # into the string representing the comparison
> > # operator (i.e. ">=" and the actual value we are
> > going
> > # to compare the table records against from the
> > input
> > # pattern, (i.e. "5"). So, for example, ">5"
> > would be
> > # split into ">" and "5".
> > r = re.search('[\s]*[\+-]?\d', pattern)
> > if self.field_types[fieldPos] == int:
> > patternValue = int(pattern[r.start():])
> > elif self.field_types[fieldPos] == float:
> > patternValue = float(pattern[r.start():])
> > else:
> > patternValue = pattern[r.start():]
> > new_patterns.append(
> > [self.cmpFuncs[pattern[:r.start()]],
> > patternValue]
> > )
>
> > fieldPos_new_patterns = zip(fieldNrs, new_patterns)
> > maxfield = max(fieldNrs)+1
>
> > # Record current position in table. Then read first detail
> > # record.
> > fpos = fptr.tell()
> > line = fptr.readline()
>
> > # Loop through entire table.
> > while line:
> > # Strip off newline character and any trailing spaces.
> > line = line[:-1].strip()
> > try:
> > # If blank line, skip this record.
> > if line == "": raise 'No Match'
> > # Split the line up into fields.
> > record = line.split("|", maxfield)
>
> > # Foreach correspond field and pattern, check to
> > see
> > # if the table record's field matches
> > successfully.
> > for fieldPos, pattern in fieldPos_new_patterns:
> > # If the field type is string, it
> > # must be an exact match or a regular
> > expression,
> > # so we will compare the table record's field
> > to it
> > # using either '==' or the regular expression
> > # engine. Since it is a string field, we will
> > need
> > # to run it through the unencodeString
> > function to
> > # change any special characters back to their
> > # original values.
> > if self.field_types[fieldPos] == str:
> > try:
> > if useRegExp:
> > if not pattern.search(
> > self._unencodeString(record
> > [fieldPos])
> > ):
> > raise 'No Match'
> > else:
> > if record[fieldPos] != pattern:
> > raise 'No Match'
> > except Exception:
> > raise KBError(
> > 'Invalid match expression for %s'
> > % self.field_names[fieldPos])
> > # If the field type is boolean, then I will
> > simply
> > # do an equality comparison. See comments
> > above
> > # about why I am actually doing a string
> > compare
> > # here rather than a boolean compare.
> > elif self.field_types[fieldPos] == bool:
> > if record[fieldPos] != pattern:
> > raise 'No Match'
> > # If it is not a string or a boolean, then it
> > must
> > # be a number or a date.
> > else:
> > # Convert the table's field value, which
> > is a
> > # string, back into it's native type so
> > that
> > # we can do the comparison.
> > if record[fieldPos] == '':
> > tableValue = None
> > elif self.field_types[fieldPos] == int:
> > tableValue = int(record[fieldPos])
> > elif self.field_types[fieldPos] == float:
> > tableValue = float(record[fieldPos])
> > # I don't convert datetime values from
> > strings
> > # back into their native types because it
> > is
> > # faster to just leave them as strings
> > and
> > # convert the comparison value that the
> > user
> > # supplied into a string. Comparing the
> > two
> > # strings works out the same as comparing
> > two
> > # datetime values anyway.
> > elif self.field_types[fieldPos] in (
> > - Hide quoted text -
>
> - Show quoted text -...
>
> read more ยป
Okay. Thanks.
More information about the Python-list
mailing list