[Tutor] Iterators, example (need help)

eryksun eryksun at gmail.com
Tue Oct 23 15:52:13 CEST 2012


On Mon, Oct 22, 2012 at 6:30 PM, Bryan A. Zimmer <baz at comcast.net> wrote:
>
> ignore1='''
>
> This program works to do what I set out to do as a first step
> BAZ 10/19/2012
>
> '''

If this isn't meant to be a module docstring, leave it where it is,
but remove the assignment to ignore1. Unassigned triple-quoted strings
are the closest thing in Python to C-style /* multi-line comments */.
This works because the compiler ignores unassigned literal
strings/numbers, as the following example shows:

    >>> code = compile('''\
    ... 0
    ... """
    ... multi-line
    ... comment
    ... """
    ... ''', filename='<string>', mode='exec')

    >>> code.co_consts
    (None,)

If the number 0 and the string were't ignored, they'd be in co_consts.
This is a tuple of immutable objects used by Python bytecode, such as
literal numbers, strings (including unicode), tuples, and the
singleton None. 3.x adds True, False, Ellipsis, and frozenset. (I
probably forgot something, but you get the idea.)

If the string is meant to be a docstring, on the other hand, put it on
the first line before your imports. In this special case, the compiler
creates a __doc__ constant, which is assigned as an attribute of the
module. Here's a skeleton of the process:

    >>> code = compile('"a docstring"', '<string>', 'exec')
    >>> dis.dis(code)
      1           0 LOAD_CONST               0 ('a docstring')
                  3 STORE_NAME               0 (__doc__)
                  6 LOAD_CONST               1 (None)
                  9 RETURN_VALUE

    >>> mod = types.ModuleType('mod')
    >>> vars(mod)
    {'__name__': 'mod', '__doc__': None}

    >>> exec code in vars(mod)

    >>> vars(mod).keys()
    ['__builtins__', '__name__', '__doc__']
    >>> mod.__doc__
    'a docstring'

Executing the code in the module also added __builtins__ to the
namespace, so built-in functions and types are available. A normal
import would also set the __file__ and __package__ attributes.


Regarding your Env class, I hope you'd use os.environ.iteritems() in practice.

>     def __next__(self,master=None):

In 2.x, this should be next(). In 3.x, it's __next__().

http://docs.python.org/library/stdtypes.html#iterator.next
http://docs.python.org/py3k/library/stdtypes.html#iterator.__next__


StringVar objects s1 and s2 should be attributes of the App instance,
not global variables.  Also, as it is, since you aren't rebinding s1
or s2 in next(), there's no technical reason to declare them with the
'global' keyword in next().

http://docs.python.org/reference/simple_stmts.html#the-global-statement

Don't needlessly parenthesize expressions in statements such as if,
return, etc. Python doesn't require it, so it's just symbol noise. For
example, use:

    if x:
        return x

x, y, d, v, and i are unhelpful attribute names. I strongly recommend
using descriptive names such as current_key, current_value. It helps a
lot when you're updating code later on, especially if you aren't the
original author.

As to the next() method itself, I'd keep it simple. Return the
key/value tuple if self._index < len(self.keys), and otherwise raise
StopIteration. I wouldn't conflate the implementation of next() with
updating the StringVar instances s1 and s2. The "Next" button can use
a method defined in App to iterate the Env instance and update the
strings.


More information about the Tutor mailing list