[Python-ideas] Deprecate str.find

Mike Graham mikegraham at gmail.com
Fri Jul 15 19:18:51 CEST 2011


On Fri, Jul 15, 2011 at 1:06 PM, Bruce Leban <bruce at leapyear.org> wrote:
> It seems to me that the solution is that you should never use find and use
> index instead. You could even modify pylint/etc. to flag any use of find as
> an error.
> That doesn't mean it should be deprecated so everyone else has to follow
> you. Deprecated now => removed in the future. While many can agree that
> warnings in the documentation about common mistakes in using APIs is a good
> thing, that doesn't translate into consensus that we should remove the API
> that might be misused. The documentation already says "The find() method
> should be used only if you need to know the position of sub. To check if sub
> is a substring or not, use the in operator."
> There is *no* general solution to the problem of people misusing APIs. Even
> with index someone can still write
>
> if s.index(sub):
>
> which probably doesn't do what they were thinking. Should we remove that
> too?

The case of "if s.index(sub):" as a misspelling of "if sub in s:" is
not nearly as errorprone as the case of "if s.find(sub):". For one,
"s.find(sub)" *sounds* like it might be true if you can find sub in s
and not true if sub cannot be found. With str.index, the fact the
return value is going to be an index is made clear. For two, str.find
can fail silently in more cases than the str.index case can fail
silently. For three, I've never see a learner write "if s.index(sub)"
though I have seen several mistakenly write the "if s.find(sub)"
version.

> Note that one reason people might prefer find over index is that exceptions
> constrain how you write the code:
>
> try:
>     i = s.index(sub)
>     do lots of stuff with s and i
> except ValueError:
>     result = 'not found'
>
> In this case the try wraps way too much code so it could catch a ValueError
> in the middle of 'stuff'. Here's correct code:
>
> try:
>     i = s.index(sub)
>     do_more = True
> except:
>     result = 'not found'
>     do_more = False
> if do_more:
>     do lots of stuff with s and i
>
> Do you think that's better than:
>
> i = s.find(sub)
> if i < 0:
>     result = 'not found'
> else:
>     do lots of stuff with s and i

Are you familiar with the "else" clause of a try/except suite? It
already handles writing the "right" version nicely.

try:
    i = s.index(sub)
except IndexError:
    result = 'not found'
else:
     do lots of stuff with s and i

> --- Bruce

Mike



More information about the Python-ideas mailing list