D
Duncan Booth
Joel said:It basically boils down to "don't ever use 'is' unless pushed into a
corner, and nevermind what PEP8 says about it".
A quick grep[*] of the Python library shows the following common use-cases
for 'is'. The library isn't usually a good indicator of current style
though: a lot of it was forced to do things differently at the time when it
was written. (Also, my search includes site-packages so this isn't all
standard lib: I found 5091 uses of the keyword 'is').
Comparison against None '<expr> is None' or '<expr> is not None' are by far
the commonest.
Comparison against specific types or classes are the next most common (in
the standard library '<expr> is type([])' although if the code were
rewritten today and didn't need backward compatability it could just do
'<expr> is list'.
Comparison against sentinal or marker objects e.g. in the standard library
this is usually a constant set to [].
Other singletons e.g. NotImplemented
code.py has:
if filename and type is SyntaxError:
which might be better style if it used 'issubclass' rather than 'is'.
cookielib.py has:
if port is None and port_specified is True:
naughty.
difflib.py uses:
if a is self.a:
return
in SequenceMatcher to avoid recomputing related values when changing one or
other of the sequences.
doctest does some fairly advanced identity testing. It also has:
SUCCESS, FAILURE, BOOM = range(3) # `outcome` state
...
if outcome is SUCCESS:
...
elif outcome is FAILURE:
...
elif outcome is BOOM:
fnmatch.py uses 'is' on some module names to optimise out a function call.
optparse.py uses 'is' to test for non-default options, but it has some
pretty dubious ways of generating the values it tests against:
NO_DEFAULT = ("NO", "DEFAULT")
SUPPRESS_HELP = "SUPPRESS"+"HELP"
SUPPRESS_USAGE = "SUPPRESS"+"USAGE"
....
if default_value is NO_DEFAULT or default_value is None:
default_value = self.NO_DEFAULT_VALUE
....
if not option.help is SUPPRESS_HELP:
....
elif usage is SUPPRESS_USAGE:
sre defines a bunch of constants strings like an enumeration and uses 'is'
to test them.
threading.py does identity checking on threads:
me = currentThread()
if self.__owner is me:
Non standard library:
Spambayes has:
if val is True:
val = "Yes"
elif val is False:
val = "No"
when displaying configuration options to the user.
zsi does things like:
if item.isSimple() is True:
if item.content.isRestriction() is True:
self.content = RestrictionContainer()
elif item.content.isUnion() is True:
self.content = UnionContainer()
elif item.content.isList() is True:
self.content = ListContainer()
ick.
[*] I discovered a neat feature I didn't know my editor had: grepping for
"<[c
ignoring it everywhere it isn't a keyword.