[Python-Dev] Adding a conditional expression in Py3.0
Steve Holden
steve at holdenweb.com
Thu Sep 29 17:54:46 CEST 2005
Guido van Rossum wrote:
> On 9/29/05, Raymond Hettinger <raymond.hettinger at verizon.net> wrote:
>
>>FWIW, I scanned the standard library for all the and/or pairings where a
>>conditional expression was applicable. This sampling can serve as a
>>reference for what "typical" uses would look like in real Python code as
>>created by a number of different authors.
>>
>>It only takes about five minutes to try out a given syntax proposal on
>>all the fragments listed below. That short exercise provides an
>>excellent insight into the look and feel of each proposal in real world
>>code.
>
>
> I did this for my favorite proposal, and ended up with the list shown
> further down below.
>
> I think they all looks great!
>
The fact that so few were found in whole of the standard library does
put the use case into question, though, no? Though I am sure more could
be found with a more thorough scan.
> The only problem is that it's not easy to come up with a regex-based
> way to transform
>
> C and X or Y
>
> into
>
> X if C else Y
>
> because it's hard to determine where C starts. So I recommend that
> people leave existing and/or code alone but start writing if/else
> expressions in new code only. After all there's nothing wrong with
> and/or.
>
> cgitb.py: file = os.path.abspath(file) if file else '?'
> cgitb.py: formatter = html if self.format == "html" else text
> compileal1.py: cfile = fullname + ('c' if __debug__ else 'o')
> csv.py: a if (quotes[a] > quotes[b]) else
> b, quotes.keys())
> csv.py: a if (delims[a] > delims[b]) else
> b, delims.keys())
> csv.py: modes[char] = reduce(lambda a, b: a if
> a[1] > b[1] else b,
> DocXMLRPCServer.py: anchor = (cl.__name__ if cl else '') + '-' + name
> fileinput.py: "*" if isfirstline()
> else "", line)
> formatter.py: self.writer.send_paragraph((1) if blankline else 0)
> gettext.py: __builtin__.__dict__['_'] = self.ugettext if
> unicode else self.gettext
> imaplib.py: l = map(lambda x:'%s: "%s"' % (x[0], '"
> "'.join(x[1]) if x[1][0] else ''), l)
> imputil.py: _suffix_char = 'c' if __debug__ else 'o'
> keyword.py: iptfile = args[0] if args else "Python/graminit.c"
> pickle.py: self.write(NEWTRUE if obj else NEWFALSE)
> pickle.py: self.write(TRUE if obj else FALSE)
> pickletools.py: "<unknown>" if pos is
> None else pos,
> py_compile.py: cfile = file + ('c' if __debug__ else 'o')
> pydoc.py: return re.sub('^ *\n', '', rstrip(result)) if result else ''
> pydoc.py: anchor = (cl.__name__ if cl else '') + '-' + name
> pydoc.py: lhs = '<strong>%s</strong> = ' % name if name else ''
> pydoc.py: contents = [doc + '\n'] if doc else []
> pydoc.py: line = (name + ' = ' if name else '') + repr
> pydoc.py: line = (self.bold(name) + ' = ' if name else '') + repr
> pydoc.py: host = '127.0.0.1' if (sys.platform == 'mac')
> else 'localhost'
> pydoc.py: font = ('helvetica', 8 if sys.platform == 'win32' else 10)
> robotp~1.py: return (self."Allow" if allowance else
> "Disallow")+": "+self.path
> telnet~1.py: 'DO' if cmd == DO else
> 'DONT', ord(opt))
> telnet~1.py: 'WILL' if cmd == WILL else
> 'WONT', ord(opt))
> thread~1.py: "s" if n!=1 else "")
> token.py: inFileName = args[0] if args else "Include/token.h"
> tokenize.py: yield (parenlev > NL if 0 else NEWLINE,
> unittest.py: return doc.split("\n")[0].strip() if doc else None
> unittest.py: return doc.split("\n")[0].strip() if doc else None
> unittest.py: (run, run != "s" if 1 else
> "", timeTaken))
> urllib.py: safe_map[c] = c if (c in safe) else ('%%%02X' % i)
> urllib2.py: type = 'I' if file else 'D'
> xdrlib.py: print 'succeed' if pred(x) else 'failed', ':', x
> xmlrpclib.py: write("1" if value else "0")
>
Having though about it more closely, the reason I believe it might
confuse newbies is because until the "else" comes along the construct
can easily be read as a statement with a conditional suffix, and it's
only after you read the "else" it becomes obvious that it's the
expression that's conditional.
I realise that this reading will become habitual once this proposal is
put into the language, but I do think this will be a source of confusion
to newcomers (who should anyway be steered away from all the magic of
ternary expressions, list comprehensions, generator expressions and the
like.
I would argue for mandatory parentheses around the expression, leaving
room later (probably after Guido is no longer around to be sick at the
site of it) for:
def f(condition):
return something if condition # no else!
return somethingElse
not-expecting-this-to-fly-ly y'rs - steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.pycon.org
More information about the Python-Dev
mailing list