"also" to balance "else" ?

Ron Adam rrr at ronadam.com
Wed Jun 15 00:40:10 EDT 2005


Andrew Dalke wrote:

> As someone else pointed out, that problem could be resolved in
> some Python variant by using a different name, like "at end".
> Too late for anything before P3K.

It was pointed out to me the logic of the else is consistant with the if 
in reguard to the loop test it self, it's just when you apply it to the 
loop as a whole, the resulting expected code flow becomes counter 
intuitive.  So it's isn't so much of a problem as it is a gotcha, or 
something that has the potential to be a gotcha.

I was thinking that changing the else to an also, would be a small 
change, but because I miss understood just what it was testing for.  It 
would not be correct to change it.

Maybe just removing it from python 3k would be the better choice?

Adding a seperate loop enter/exit test to determine if a loop was exited 
with break after it has started, would be a seperate issue and one that 
would need more support than the smaller change I was thinking it would 
require.


>>>That is ... funky.  When is it useful?
>>
>>Any time you've writen code that repeats a section of code at the end of
>>all the if/elif statements or sets a variable to check so you can
>>conditionally execute a block of code after the if for the same purpose.
> 
> Let me clarify.  When is it useful in real code?  Most cases
> I can think of have corner cases which treat some paths different
> than others.

Here are some examples that I've found from the libary where the program 
flow matches the if-elif-also logic but was writen differntly.


#from urllib.py
     def redirect_internal(self, url, fp, errcode, errmsg, headers, data):
         if 'location' in headers:
             newurl = headers['location']
         elif 'uri' in headers:
             newurl = headers['uri']
         else:
             return
         void = fp.read()
         fp.close()
         # In case the server sent a relative URL, join with original:
         newurl = basejoin(self.type + ":" + url, newurl)
         return self.open(newurl)


#could be...
     def redirect_internal(self, url, fp, errcode, errmsg, headers, data):
         if 'location' in headers:
             newurl = headers['location']
         elif 'uri' in headers:
             newurl = headers['uri']
         also:
             void = fp.read()
             fp.close()
             # In case the server sent a relative URL,
             #   join with original:
             newurl = basejoin(self.type + ":" + url, newurl)
             return self.open(newurl)



#from difflib.py
     tag = ''
     if i < ai and j < bj:
         tag = 'replace'
     elif i < ai:
         tag = 'delete'
     elif j < bj:
         tag = 'insert'
     if tag:
         answer.append( (tag, i, ai, j, bj) )

#could be...
     if i < ai and j < bj:
         tag = 'replace'
     elif i < ai:
         tag = 'delete'
     elif j < bj:
         tag = 'insert'
     also:
         answer.append( (tag, i, ai, j, bj) )

This one is simular to the code I was writing when I want'ed to use an 
inverse else.  It doesn't require 'tag' to be initialized before hand.


# from imputil.py
class BuiltinImporter(Importer):
     def get_code(self, parent, modname, fqname):
         if parent:
             # these modules definitely do not occur within a package 
context
             return None

         # look for the module
         if imp.is_builtin(modname):
             type = imp.C_BUILTIN
         elif imp.is_frozen(modname):
             type = imp.PY_FROZEN
         else:
             # not found
             return None

         # got it. now load and return it.
         module = imp.load_module(modname, None, modname, ('', '', type))
         return 0, module, { }

#could be...
class BuiltinImporter(Importer):
     def get_code(self, parent, modname, fqname):
         if parent:
             # these modules definitely do not occur
             #   within a package context
             return None

         # look for the module
         if imp.is_builtin(modname):
             type = imp.C_BUILTIN
         elif imp.is_frozen(modname):
             type = imp.PY_FROZEN
         also:
             # got it. now load and return it.
             module = imp.load_module(modname, None, modname, \
                      ('', '', type))
             return 0, module, { }

         # not found
         # return None


None of these are big or dramatic changes of the sort that I couldn't 
live without.  Finding examples in the library is more difficult than I 
expected, so while this seems like a good idea... I'm not convinced yet 
either.  But that is why I posted is to find out what other thought.

Regurds, Ron




More information about the Python-list mailing list