There must be a better way

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Apr 20 20:06:25 EDT 2013


On Sat, 20 Apr 2013 19:46:07 -0400, Colin J. Williams wrote:

> Below is part of a script which shows the changes made to permit the
> script to run on either Python 2.7 or Python 3.2.
> 
> I was surprised to see that the CSV next method is no longer available.

This makes no sense. What's "the CSV next method"? Are you talking about 
the csv module? It has no "next method".

py> import csv
py> csv.next
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'next'


Please *define your terms*, otherwise we are flailing in the dark trying 
to guess what your code is supposed to do. The code you provide cannot 
possible work -- you use variables before they are defined, use other 
variables that are never defined at all, reference mysterious globals. 
You even close a file before it is opened!

Please read this:

http://sscce.org/

and provide a *short, self-contained, correct example* that we can 
actually run.

But in the meantime, I'm going to consult the entrails and try to guess 
what you are doing: you're complaining that iterators have a next method 
in Python 2, and __next__ in Python 3. Am I correct?

If so, this is true, but you should not be using the plain next method in 
Python 2. You should be using the built-in function next(), not calling 
the method directly. The plain next *method* was a mistake, only left in 
for compatibility with older versions of Python. Starting from Python 2.6 
the correct way to get the next value from an arbitrary iterator is with 
the built-in function next(), not by calling a method directly.

(In the same way that you get the length of a sequence by calling the 
built-in function len(), not by calling the __len__ method directly.)

So provided you are using Python 2.6 or better, you call:

next(inData)

to get the next value, regardless of whether it is Python 2.x or 3.x.

If you need to support older versions, you can do this:

try:
    next  # Does the built-in already exist?
except NameError:
    # No, we define our own.
    def next(iterator):
        return iterator.next()

then just use next(inData) as normal.



-- 
Steven



More information about the Python-list mailing list