On 01/02/2014 01:44 PM, John Allsup wrote:
The point of my original post was that, whilst C's
  if( x = 2 ) { do something }
and
  if( x == 2 ) { do something }
are easy to confuse, and a source of bugs, having a construct like follows:

if x == 2:
    do something # what happens at present
if testFunc() as x:
    do something with x

using the 'as' syntax that appears with 'with' and 'except', would allow
for the advantages of C style assignments in conditionals but without the easy confusion, since here the syntax is significantly different between assignment and equality testing (rather than a character apart as happens with C).

This occurs further down in my original post (past the point where you inserted your reply).

Another post suggested a workaround by defining a 'pocket' class, for which I am grateful.

John

Sorry. I shot off my answer before reading the whole post. That's never a good idea.


After reading to the end, I rather like your suggestion. It works well in your example, , nicely avoids the C/C++ trap, and has some consistency with other parts of Python.

Gary Herron




On 02/01/2014 19:27, Gary Herron wrote:
On 01/02/2014 09:20 AM, John Allsup wrote:
Hi,

This is my debut on this list.

In many languages, such as C, one can use assignments in conditionals
and expressions.  The most common, and useful case turns up when you
have if/else if/else if/else constructs. Consider the following
non-working pseudoPython.

import re
r1 = re.compile("hello (\d)")
r2 = re.compile("world([!?])")

w = "hello world!"

if m = r1.search(w):

This kind of thing in C/C+ has always been the source of much confusion
and potential errors, because the construct is so similar to an "=="
test.  Python does not replicate this potential for confusion. Instead,
we use two lines of code, an assignment and then the test.   If you find
that extra line of code inconvenient than at least you can take comfort
in the fact that it is clearer code.  If you are still not convinced,
... then sorry, that's just the way Python is.

Gary Herron


    handleMatch1(m)
elif m = r2.search(w):
    handleMatch2(m)
else:
    print("No match")

If the regular expressions are complex, running them multiple times
(once to test, another to capture groups) isn't ideal.  On the other
hand, at present, one has to either do:

m = r1.search(w)
if m:
    handleMatch1(m)
else:
    m = r2.search(w)
    if m:
        handleMatch2(m)
    else:
        print("No match")

if not running unnecessary matches, yet capturing groups in the event
of a successful match, is what is desired.

If there are multiple tests, the indentation gets silly.  This arises
because having removed the ability to assign in an expression, there
is no way to save the result of a function call that is used in a
conditional at all.

I am aware that this facility in C is a source of bugs, = being only a
typo away from the more common ==.  With exceptions and contexts, we
have:

with open("file") as f:
    doSomethingWith(f)

try:
    trySomething()
except SomethingRandomGoingWrong as e:
    lookAtException(e)

What I am wondering is why not use a similar syntax with if, so that
one could do

if r1.search(w) as m:
    g = m.groups()
    print(g[1])

This would remove the risk of errors by typos since the syntax for
equality testing (if x == y:) is completely different from that for
assigning in a conditional (which would look like 'if y as x:'

Related would be to have Nonetype work with contexts such that

with None as x:
    doStuff(x)

would do nothing.  This would allow things like:

with maybeGetSomething as x:
    doStuff(x)

to call doStuff(x) within a context of maybeGetSomething returns
something, or do nothing if nothing is returned.  (Adding an else-like
keyword to with, or possibly using else in that context, would allow
one to process a non-None object if returned, or else do something in
response to a None object being returned by the maybeGetSomething.)

Just a thought.

Or what is the current 'Pythonic' way to do something like:

if x = func1():
    do1(x)
elif x = func2():
    do2(x)
elif x = func3():
    do3(x)
elif x = func4():
    do4(x)
else:
    do5()

where each of func1,func2,func3,func4 have side effects so that func2
is tested if and only if func1 returns a false value, func1 must be
called only once, and what is returned from func1 must be available to
the code inside the if block?


John




--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to