Alternative iterator syntax
Tim Hochberg
tim.hochberg at ieee.org
Wed Feb 21 14:24:28 EST 2001
"Michael Hudson" <mwh21 at cam.ac.uk> wrote in message
news:m37l2kszu7.fsf at atrus.jesus.cam.ac.uk...
> aahz at panix.com (Aahz Maruch) writes:
>
> > In article <mailman.982769240.31345.python-list at python.org>,
> > Huaiyu Zhu <hzhu at users.sourceforge.net> wrote:
> > >
> > > [...]
> >
> > I'm not sure where to put this question, so I'm just deleting all of
> > Huaiyu's text.
> >
> > How does one get UserDict.keys (note: no parens here) to return an
> > iterator? Normally this will simply return a reference to the method.
>
> class _Keys:
> def __init__(self, dict):
> self.dict = dict
> def __contains__(self, item):
> return self.dict.has_key(item)
> def __call__(self):
> return self.dict.keys()
> ... etc ...
>
> class UserDict:
> def __init__(self, dict=None):
> if data is None:
> data = {}
> self.data = dict
> self.keys = _Keys(dict)
> ... etc ...
>
> Not *very* different from how you'd implement this in C, really.
>
> Hmm, you might want to have the _Keys object hang on the instance
> rather than the dict if assigning to the .data member of UserDict is
> allowed. Which would create a circular reference, but we don't have
> to worry about that too much now...
I don't think this will work right though. Consider:
for k in aUserDict.keys:
# Do some stuff
for k in aUserDict.keys:
# Do some more stuff
The way this is implemented here the second loop would bail out immediately
because there is only a single iterator for a given instance and it is
already exhausted. One could imagine even odder instances where one broke
out halfway through the first loop; the second loop would then start
iterating halfway through the dictionaries keys. To get this to work "right"
one would need to generate a new iterator using getattr magic every time the
attribute was asked. Something like:
def UserDict:
def __attr_keys_(self, op, value):
if "op" == "get": return _Keys(dict)
else: raise ValueError("keys not writable")
Here I've used the syntax from the draft "Attribute Access Handlers" PEP.
This makes the keys attribute sufficiently magical that it makes me a bit
nervous. On the other hand, one could do kinda cool stuff like:
myKeys = aUserDict.keys # Get my own copy of the keys iterator
for key in myKeys:
# Do Stuff
if key == someSpecialKey:
break
# Do some processing out of the loop
for key in myKeys: # resume where we left off
# Do some other stuff
Sure that example's a little contrived, but I'm sure that must be usefule
somewhere <0.8 wink>.
-tim
More information about the Python-list
mailing list