my first class: Args

Scott David Daniels Scott.Daniels at Acm.Org
Sun Aug 29 00:01:13 EDT 2004


Peter Kleiweg wrote:

...
> This is the only instance I didn't follow your recommendation to
> use try/except. It is a binary choice: do we use files given on
> the command line or stdin? Neither is more natural than the
> other. Also, it splits up lines of code that belong together.
> 
> Here is my re-write:
> 
>     def __iter__(self):
>         "iterator: set-up"
>         if self._argv:
>             self.infile = self._argv.pop(0)
>             self._in = open(self.infile, 'r')
>             self._stdin = False
>         else:
>             if sys.stdin.isatty():
>                 self.usage()  # Doesn't return
>             self.infile = '<stdin>'
>             self._in = sys.stdin
>             self._stdin = True
>         return self
> 
> The exceptional case is there be no input, and the simplest test
> here seems to be a simple if-statement.

Perfectly fine.  I probably lean on the "don't look before you leap"
a bit too heavily.  Remember, writing code is like writing in your
native language; it is more important to be clear than to match a
style.  Notice that you have a bit more structure now than originally.
A single top-level conditional is simpler to read; less needs to be
read to understand what is going on.

>>def demo():
>>     ...
>>
>>if __name__ == '__main__':
>>     demo()

> That doesn't seem very useful. It depends on command line
> arguments. If they are missing, it does a sys.exit(), probably
> not what you want unless you run the module stand-alone.

I missed the sys.argv -- here is a sketch of a slightly better rewrite:

 > class Args:
 >     """..."""
 >     def __init__(self,usage='Usage: %(progname)s [opt...] [file...]'):
 >         "init, usage string: embed program name as %(progname)s"
 >         self.progname = os.path.basename(sys.argv[0])
 > ...
 >         self._argv = sys.argv[1:]
   class Args:
       """..."""
       def __init__(self, progname, args,
                    usage='Usage: %(progname)s [opt...] [file...]'):
           "usage string: embed program name as %(progname)s"
           self.progname = progname
           self._argv = args
           ...


 > if __name__ == '__main__':
 >     ...

   def demo(progname, args):
       a = Args(progname, args,
         'Usage: %(progname)s [-a value] [-b value] [-c] word [file...]')
       ...

if __name__ == '__main__':
      demo(sys.argv[0], sys.argv[1:])


---

In idle, the exit can be stopped (so it is not a huge worry).  If
nothing else you can do:
         try:  demo('name', ['abc', 'def']}
         except SystemExit: pass

Cutting into sys.argv is, however, a bit tougher usually.


-Scott David Daniels
Scott.Daniels at Acm.Org



More information about the Python-list mailing list