Naming conventions for iterator methods?

J

John J. Lee

How do people name their iterator methods / functions?

eg. .iter_foo(), .foo_iter(), .iterfoo(), .fooiter(), .foos(), ...?

Of course, dicts have .iterkeys(), .itervalues() and .iteritems(), but
I don't like having words run together like that.


My particular case: I have a class that can be iterated over in
several ways, so I need to have a method other than __iter__ to return
iterators.

http://wwwsearch.sf.net/bits/pullparser.py


The class pullparser.PullParser can iterate over HTML tokens (which
includes tags, comments, declarations, etc.) or just over the tokens
representing tags, skipping all other tokens. So __iter__ returns an
iterator over tokens, and tag_iter() over tags. Then I wondered if I
should be following a standard naming convention. There's a method
..get_tag(), so I guess the should be related to that in some obvious
way.


John
 
F

Francis Avila

John J. Lee wrote in message said:
How do people name their iterator methods / functions?

eg. .iter_foo(), .foo_iter(), .iterfoo(), .fooiter(), .foos(), ...?

Of course, dicts have .iterkeys(), .itervalues() and .iteritems(), but
I don't like having words run together like that.

Well, you have already discovered and rejected what little convention there
is. ;)

It seems that the emerging convention is .iter<noun>s() for methods, and
i said:
The class pullparser.PullParser can iterate over HTML tokens (which
includes tags, comments, declarations, etc.) or just over the tokens
representing tags, skipping all other tokens. So __iter__ returns an
iterator over tokens, and tag_iter() over tags. Then I wondered if I
should be following a standard naming convention. There's a method
.get_tag(), so I guess the should be related to that in some obvious
way.

I would have done .itertags(). This seems the most natural to me: iter +
plural of thing to be iterated. I suppose it's just because it follows the
dict convention, but it fits my way of thinking naturally, too.

I don't like tag_iter(), because it seems more a noun than a verb. I almost
expect it to *be* the iterator rather than *return* one. Having a verb as a
function name is clearer.

All this said, it's more important to be consistent with yourself than with
the convention. *That* said, you'll be loved more if your self-consistency
is also consistent with convention. :)
 
?

=?iso-8859-1?Q?Fran=E7ois?= Pinard

[John J. Lee]
How do people name their iterator methods / functions?
eg. .iter_foo(), .foo_iter(), .iterfoo(), .fooiter(), .foos(), ...?

I took the habit of naming such methods and functions with names
starting with `all_', so I can write:

for name in all_names():
do something

or maybe:

tokens = all_tokens()
...
token = tokens.next()
...

I find this more legible than forcing the string `iter' here and there,
and leaves a bit more freedom to change the code later -- let's say, if
I ever want to substitute a solid list for the iterator. I can keep the
`all_' prefix, while I would feel uncomfortable it were some `iter' in
the names. Granted, if I want to use `.next()', I'll have to plunk one
more `iter()' in the code.
 
P

Peter Otten

John said:
How do people name their iterator methods / functions?

eg. .iter_foo(), .foo_iter(), .iterfoo(), .fooiter(), .foos(), ...?

Of course, dicts have .iterkeys(), .itervalues() and .iteritems(), but
I don't like having words run together like that.

My personal naming convention is not yet stable, but I currently favour
foos(). I think iterkeys() etc. were only introduced because there already
were methods like keys() returning the corresponding list.
These I now tend to omit and instead make it explicit when I need a list, e.
g.

alltags = list(parser.tags())

and instead of parser.filtertags(pred):

sometags = [t for t in parser.tags() if pred(t)]

When all returned sequences are iterators, a special prefix/suffix seems
pointless and you may wonder how to name the few exceptions:

list_foo(), foo_list(), listfoo(), foolist(), foos(), ...

:)

Peter
 
J

John J Lee

[John J. Lee]
How do people name their iterator methods / functions?
eg. .iter_foo(), .foo_iter(), .iterfoo(), .fooiter(), .foos(), ...?

I took the habit of naming such methods and functions with names
starting with `all_', so I can write:

for name in all_names():
do something

I don't like that, because often my iterator-returning methods take
arguments to restrict the iterees: shop.iter_cheeses(variety="smelly").
or maybe:

tokens = all_tokens()
...
token = tokens.next()
...

I just realised some of these methods of mine don't actually return
iterators, but merely objects supporting the iterator protocol. In other
words, the returned objects have an .__iter__() method, but not a .next()
method (usually because I've quickly implemented the method by returning a
sequence, leaving the way open for a later reimplementation that, eg.,
returns a lazy iterator). Would that surprise people from a method named
.iter_foo()?

I find this more legible than forcing the string `iter' here and there,
and leaves a bit more freedom to change the code later -- let's say, if
I ever want to substitute a solid list for the iterator. I can keep the
`all_' prefix, while I would feel uncomfortable it were some `iter' in
the names. Granted, if I want to use `.next()', I'll have to plunk one
more `iter()' in the code.

That's one data point :)

I think I'll go with .foos(), for the same reason you choose .all_foos()
-- it'll make people read the docs if they need to know whether it's a
sequence, iterator, or object supporting the iterator protocol.


John
 
J

Jp Calderone

[snip]

I just realised some of these methods of mine don't actually return
iterators, but merely objects supporting the iterator protocol. In other
words, the returned objects have an .__iter__() method, but not a .next()
method (usually because I've quickly implemented the method by returning a
sequence, leaving the way open for a later reimplementation that, eg.,
returns a lazy iterator). Would that surprise people from a method named
.iter_foo()?

Yes. return "iter(something)" instead of just "something".

Jp


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQE/6E/cedcO2BJA+4YRArn1AKC61dsG0tkxVt38R7a2/yLiIv46SgCgivnl
HNCarHjfOptZmDOwxtdDa50=
=hVAG
-----END PGP SIGNATURE-----
 
?

=?iso-8859-1?Q?Fran=E7ois?= Pinard

[John J Lee]
I think I'll go with .foos(), for the same reason you choose .all_foos()
-- it'll make people read the docs if they need to know whether it's a
sequence, iterator, or object supporting the iterator protocol.

I surely thought about using a suffix `s'. I do not know how frequent
the problem is in English, but when I write in-house Python, I use
French identifiers[1], and many words already have an `s' suffix in the
singular form, the spelling does not change when pluralised.
[François Pinard]
I took the habit of naming such methods and functions with names
starting with `all_', so I can write:
for name in all_names():
do something
I don't like that, because often my iterator-returning methods take
arguments to restrict the iterees: shop.iter_cheeses(variety="smelly").

In my humble opinion,

for cheese in shop.all_cheeses(variety="smelly"):
do something

would still be quite legible, and not shocking at all. In French,
`all_' would become `tous_' or `toutes_', of course.
I just realised some of these methods of mine don't actually return
iterators, but merely objects supporting the iterator protocol.

It may be a worth idea systematically returning iterables instead of
iterators. Yet, I think an iterator shall formally provide itself
through its `__iter__' method.

In practice, I noticed that most of my `all_' functions or methods are
based on generators. So clean! :) These are very useful.

------------------------------------------------------------------------
[1] I mean, nearly French, as the necessary diacritics may not be
used in Python identifiers, which is a common and constant source of
displeasure to those of us who especially like working in French. Oh,
Python does not differ on this aspect than most other programming
languages. However, as Python is so satisfying in many other areas, we
had some vague hope that he might become better in this particular one.
Especially given that, for a tiny moment, it once worked correctly for
French -- but sadly, this was the consequence of a Python bug which has
been corrected since.
 
J

John J. Lee

Peter Otten said:
John J. Lee wrote: [...]
My personal naming convention is not yet stable, but I currently favour
foos(). I think iterkeys() etc. were only introduced because there already
were methods like keys() returning the corresponding list.
These I now tend to omit and instead make it explicit when I need a list, e.
g.

alltags = list(parser.tags())

Yeah, I think you're right on both counts.

and instead of parser.filtertags(pred):

sometags = [t for t in parser.tags() if pred(t)]

Yes. Also, I have keyword arguments to some .foos() methods.

When all returned sequences are iterators, a special prefix/suffix seems
pointless and you may wonder how to name the few exceptions:

list_foo(), foo_list(), listfoo(), foolist(), foos(), ...

But a sequence is not an iterator, IIRC, because it doesn't have a
..next() method. It just "supports the iterator protocol" by virtue of
having an .__iter__() method that returns an iterator (which has both
..next() and .__iter__()).


John
 
J

John J. Lee

François Pinard said:
[1] I mean, nearly French, as the necessary diacritics may not be
used in Python identifiers, which is a common and constant source of
displeasure to those of us who especially like working in French. Oh,
Python does not differ on this aspect than most other programming
languages. However, as Python is so satisfying in many other areas, we
had some vague hope that he might become better in this particular one.
Especially given that, for a tiny moment, it once worked correctly for
French -- but sadly, this was the consequence of a Python bug which has
been corrected since.

I don't feel qualified, or morally righteous <wink> enough to have a
hard opinion on whether this would be a good thing, as an English
monoglot, but I don't see what the problem is with adding this
feature. It seems only fair and symmetrical to allow unicode
identifiers. Yes, it'd confuse the hell out of people like me to have
to read a Python program written in Korean characters. But it'd
confuse me just as much if it were written in Korean but
transliterated into Roman characters in plain old ASCII.

Has this been a problem Java, in practice?

Or is the problem simply that it's considered that there's not good
enough unicode support in editors and other tools yet? Again, I'm
surprised if that's the case with all this Java code floating around.

Has it been PEPed? Or is GvR's opinion on it obvious enough that
nobody has bothered?


John
 
J

John J. Lee

Jp Calderone said:
[snip]

I just realised some of these methods of mine don't actually return
iterators, but merely objects supporting the iterator protocol. In other [...]
returns a lazy iterator). Would that surprise people from a method named
.iter_foo()?

Yes. return "iter(something)" instead of just "something".

Good idea, thanks.


John
 
S

Serge Orlov

John J. Lee said:
François Pinard said:
[1] I mean, nearly French, as the necessary diacritics may not be
used in Python identifiers, which is a common and constant source of
displeasure to those of us who especially like working in French. Oh,
Python does not differ on this aspect than most other programming
languages. However, as Python is so satisfying in many other areas, we
had some vague hope that he might become better in this particular one.
Especially given that, for a tiny moment, it once worked correctly for
French -- but sadly, this was the consequence of a Python bug which has
been corrected since.

I don't feel qualified, or morally righteous <wink> enough to have a
hard opinion on whether this would be a good thing, as an English
monoglot, but I don't see what the problem is with adding this
feature. It seems only fair and symmetrical to allow unicode
identifiers. Yes, it'd confuse the hell out of people like me to have
to read a Python program written in Korean characters. But it'd
confuse me just as much if it were written in Korean but
transliterated into Roman characters in plain old ASCII.

There is generic problem for non-latin alphabets: keyboard is
too small to accommodate two alphabets so you have to
switch frequently between languages if you're going to type
python code with non-latin identifiers. Try it, it's pain. I wouldn't
use this feature personally.
There's an advanced keyboard switcher for rus/eng input "Punto
Switcher" that knows about rare combinations of letters and is
able to automagically switch keyboard. But I'm sceptical it will
work for code as good as for pure text. I may try it when I have
time. Anyway it's a hack.

Has this been a problem Java, in practice?

Or is the problem simply that it's considered that there's not good
enough unicode support in editors and other tools yet? Again, I'm
surprised if that's the case with all this Java code floating around.

Has it been PEPed? Or is GvR's opinion on it obvious enough that
nobody has bothered?

GvR comment:
http://mail.python.org/pipermail/python-dev/2002-July/026553.html
quote:
"Allowing non-ASCII identifiers may eventually happen, but there are
lots of reasons why it's a bad idea "

-- Serge.
 
T

Terry Reedy

John J. Lee said:
identifiers. Yes, it'd confuse the hell out of people like me to have
to read a Python program written in Korean characters. But it'd
confuse me just as much if it were written in Korean but
transliterated into Roman characters in plain old ASCII.

Maybe true for you, but for most non-Asians, transliterated ASCII
identifiers are *much* easier to read, especially if pronounce-able. If
something like (made-up) 'koguhan' appears in multiple places, recognizing
the sameness is (again for most people) much easier than with
pronunciation-unknown Korean characters.

For more discussion, try to find some of the (contentious) past threads on
the topic.

TJR
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top