i don't know "self._iterator = iter(self._container)"in next code.
in django.http :
class HttpResponse(object):
def __iter__(self):
self._iterator = iter(self._container)
开发者_运维技巧 return self
def next(self):
chunk = self._iterator.next()
if isinstance(chunk, unicode):
chunk = chunk.encode(self._charset)
return str(chunk)
i read the api :
Return an iterator object. The first argument is interpreted very differently depending on the presence of the second argument. Without a second argument, o must be a collection object which supports the iteration protocol (the
__iter__()
method), or it must support the sequence protocol (the__getitem__()
method with integer arguments starting at 0). If it does not support either of those protocols,TypeError
is raised. If the second argument, sentinel, is given, then o must be a callable object. The iterator created in this case will call o with no arguments for each call to itsnext()
method; if the value returned is equal to sentinel, StopIteration will be raised, otherwise the value will be returned. One useful application of the second form ofiter()
is to read lines of a file until a certain line is reached. The following example reads a file until "STOP" is reached:
but i also don't know what the iter function made .
i know the __iter__:
class a(object):
def __init__(self,x=10):
self.x = x
def __iter__(self):
return self
def next(self):
if self.x > 0:
self.x-=1
return self.x
else:
raise StopIteration
Please try to use the code, rather than text, because my English is not very good, thank you
An iterator can be iterated:
for item in mylist:
print item
for key,item in enumerate(mylist):
print key,":",item
for i in range(0,50):
print i
To use for item in X
, X
must be iterable.
You can make your class iterable by adding next(self)
etc, as in your sample. So with
class a(object):
def __init__(self,x=10):
self.x = x
def __iter__(self):
return self
def next(self):
if self.x > 0:
self.x-=1
return self.x
else:
raise StopIteration
Then you can do
ainst = a()
for item in aisnt:
print item
HttpResponse
is a class that can store string data. The data is stored in a member variable called _container
.
Suppose hr
is an instance of HttpResponse
with data inside it. When you call iter(hr)
then you should get back an iterator. This iterator will return data from the _container
member variable.
This class "wraps" the _container
member so that it can always return non-Unicode text. Because this class has a __iter__()
method function, when you call iter()
you are really calling the special __iter__()
method function. This method function actually does call iter()
on the _container
member variable to get an iterator for its contents. But then it saves this iterator in the _iterator
member variable, and returns self
. Now it is ready to iterate.
There is a next()
method function defined. If the type of the _container
variable is Unicode, it calls encode()
to encode the Unicode in some encoding and return non-Unicode. It uses another member variable, _charset
, to know which charset to use for the encoding. If the type of the container
variable is not Unicode, it must be an ordinary string type, and the data is simply returned unchanged.
In this way, the object "wrapped" in this class can be iterated and always return non-Unicode text.
I am surprised by this implementation of the iterator protocol. When it returns an iterator to you, it is just returning self
, so if you call iter()
twice, you do not actually get two usable iterators back. This seems like it could be dangerous. I guess Django code never does anything like that.
精彩评论