没有__iter__的for循环文档? [英] docs on for-loop with no __iter__?

查看:64
本文介绍了没有__iter__的for循环文档?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当你在X中使用for x:时,有人可以向我指出有关应该发生什么的文件

X没有__iter__

方法时的语法?我知道代码:

Can someone point me to the documentation on what''s supposed to happen
when you use the "for x in X:" syntax when X does not have an __iter__
method? I know that the code:

class S:
.... def __len __(self) :返回42

.... def __getitem __(self,i):返回i

.... for S in S():
class S: .... def __len__(self): return 42
.... def __getitem__(self, i): return i
.... for x in S():



.... print x

尝试打印所有非负整数,从0开始。(注意

__len__方法在42处没有停止它。)显然,正确的

方式是用__iter__,但可能这种行为是

记录在某个地方......


史蒂夫

-

如果你只是动词,你可以用任何语法表达。

- Bucky Katt,Get Fuzzy


.... print x

tries to print all the non-negative integers, starting with 0. (Note
that the __len__ method doesn''t stop it at 42.) Obviously, the right
way to do this is with __iter__, but presumably this behavior is
documented somewhere...

Steve
--
You can wordify anything if you just verb it.
- Bucky Katt, Get Fuzzy

推荐答案

Steven Bethard写道:
Steven Bethard wrote:
有人能指出我吗当你在X中使用for x:时,关于应该发生什么的文档。 X没有__iter__
方法时的语法?


你需要提出一个IndexError

.... def __len __(self):return 42
.... def __getitem __(self ,i):返回i


说出来


def __getitem __(self,i):

if i> = 42:提高IndexError,我

返回i


显然,正确的方法是使用__iter__,但可能是这种行为在某处记录了......
Can someone point me to the documentation on what''s supposed to happen
when you use the "for x in X:" syntax when X does not have an __iter__
method?
You need to raise an IndexError
.... def __len__(self): return 42
.... def __getitem__(self, i): return i
Make that say

def __getitem__(self, i):
if i >= 42: raise IndexError, i
return i

Obviously, the right
way to do this is with __iter__, but presumably this behavior is
documented somewhere...



http://docs.python.org/ref/sequence-types.html


]注意:for循环期望一个IndexError将为非法索引筹集

],以便在序列结束时正确检测

]。


''我可以在文档中找到所有内容(搜索docs.python.org

for __getitem__和IndexError)


查看CVS的语言参考,我发现
http://www.python.org/dev/doc/devel/ref/for.html


它声明


]套件然后为每件物品执行一次

]顺序,按升序索引的顺序。


这意味着序列被编入索引,是吗?但是如果

序列实现__iter__那么就没有

可能没有''索引'的基本概念。


这应该修复吗?


Andrew
da *** @ dalkescientific.com



http://docs.python.org/ref/sequence-types.html

] Note: for loops expect that an IndexError will be
] raised for illegal indexes to allow proper detection
] of the end of the sequence.

That''s all I can find in the docs (searched docs.python.org
for __getitem__ and IndexError )

Looking at the language reference from CVS, I found
http://www.python.org/dev/doc/devel/ref/for.html

It states

] The suite is then executed once for each item in
] the sequence, in the order of ascending indices.

That implies the sequence is indexed, yes? But if
the sequence implements __iter__ then there''s no
possibly no underlying idea of ''index''.

Should this be fixed?

Andrew
da***@dalkescientific.com


Andrew Dalke< adalke< at> mindspring.com>写道:
Andrew Dalke <adalke <at> mindspring.com> writes:
http:// docs。 python.org/ref/sequence-types.html

]注意:for循环期望为非法索引引发IndexError以允许正确检测
http://docs.python.org/ref/sequence-types.html

] Note: for loops expect that an IndexError will be
] raised for illegal indexes to allow proper detection
] of the end of the sequence.




谢谢,这就是我要找的东西。我知道它必须在那附近

。 =)大概是有理由不使用len()来确定序列结束时的

吗?


Steve



Thanks, that''s what I was looking for. I knew it had to be around there
somewhere. =) Presumably there was a reason not to use len() to determine
the end of the sequence?

Steve


" Andrew Dalke" <广告**** @ mindspring.com>在消息中写道

新闻:bM ***************** @ newsread1.news.pas.earthl ink.net ...

< snip>
"Andrew Dalke" <ad****@mindspring.com> wrote in message
news:bM*****************@newsread1.news.pas.earthl ink.net...
<snip>

查看CVS的语言参考,我发现
http://www.python.org/dev/doc/devel/ref/for.html

它声明

然后按照升序索引的顺序对该序列中的每个项目执行一次。

这意味着序列被编入索引,是吗?但是如果序列实现了__iter__那么就没有可能没有''索引'的基本概念。

这应该修复吗?

Andrew
da***@dalkescientific.com



第7.3节(来自上面给出的链接)给出了for的语法。 as:


for_stmt :: =" for target_list" in" expression_list":"套房

[" else" ":"套件]


然后开始将组件语法元素描述为,表达式

列表被评估一次;它应该产生一个序列。这似乎有点过时了,因为expression_list也可以是生成器或迭代器。


另外,for如果没有提供__iter__方法,则使用自适应方法尝试模拟迭代器

,通过连续调用__getitem__直到

引发IndexError(此错误在此内部默默吸收

伪迭代器)。


这是一个简单的测试类:(我也实现了__len__认为它将使用
限制对__getitem__的调用,但我们可以从

输出中看到它从未被调用 - 而__getitem__被调用一次

太多,告诉伪迭代器没有更多的条目)。


A级(对象):

def __init __(self,lst):

self.list_ = lst [:]


def __len __(自我):

print self .__ class __.__ name __ +" .__ len __"

返回len(self.list_)

def __getitem __(self,i):

print self .__ class __.__ name __ +" .__ getitem __ ;

返回self.list_ [i]


class A_with _iter(A):

def __iter __(self):

print self .__ class __.__ name __ +" .__ iter __"

return iter( self.list_)

for(A,A_with_iter)中的cls:


a = cls([1,2,3])


print" iterate over%s" %cls .__ name__

for i in a:

print i


print


输出:

迭代A

A .__ getitem__

1

A .__ getitem__

2

A .__ getitem__

3

A .__ getitem__


迭代A_with_iter

A_with_iter .__ iter__

1

2

3

请注意这个是最近报告的email.Message中的错误的基础

和cgi.FieldStorage。 email.Message没有实现__iter__,它的

__getitem__方法假定项目将像keyed

字典查找一样被检索,而不是使用整数序列访问。所以当__getitem__

在输入字符串上调用.lower()时,Python会抛出一个错误 - 你不能在一个int上做
lower()。


Section 7.3 (from the link given above) gives the syntax for "for" as:

for_stmt ::= "for" target_list "in" expression_list ":" suite
["else" ":" suite]

and then begins describing the component syntax elements as, "The expression
list is evaluated once; it should yield a sequence." This seems to be a bit
dated, since expression_list could also be a generator or iterator.

Additionally, "for" uses an adaptive method to try to simulate an iterator
if no __iter__ method is provided, by successively calling __getitem__ until
IndexError is raised (this error gets silently absorbed within this
pseudo-iterator).

Here is a simple test class: (I also implemented __len__ thinking that it
would be used to limit the calls to __getitem__, but we can see from the
output that it is never called - instead __getitem__ gets called one time
too many, telling the pseudo-iterator that there are no more entries).

class A(object):
def __init__(self,lst):
self.list_ = lst[:]

def __len__(self):
print self.__class__.__name__+".__len__"
return len(self.list_)

def __getitem__(self,i):
print self.__class__.__name__+".__getitem__"
return self.list_[i]

class A_with_iter(A):
def __iter__(self):
print self.__class__.__name__+".__iter__"
return iter(self.list_)
for cls in (A, A_with_iter):

a = cls([1,2,3])

print "iterate over %s" % cls.__name__
for i in a:
print i

print

output:
iterate over A
A.__getitem__
1
A.__getitem__
2
A.__getitem__
3
A.__getitem__

iterate over A_with_iter
A_with_iter.__iter__
1
2
3
Note that this is the basis for the recently reported bugs in email.Message
and cgi.FieldStorage. email.Message does not implement __iter__, and its
__getitem__ method assumes that items will be retrieved like keyed
dictionary lookups, not using integer sequence access. So when __getitem__
calls .lower() on the input string, Python throws an error - you can''t do
lower() on an int.

em = email.message_from_file(open(''MAILMESSAGE''))
for i in em:
em = email.message_from_file(open(''MAILMESSAGE''))
for i in em:


... print i
...
Traceback(最近一次调用最后一次):
文件"< stdin>",line 1,在文件中/usr/lib/python2.3/email/Message.py" ;,
第304行,在__getitem__
文件" / usr / lib / python2中。 3 / email / Message.py",
第370行,获取
AttributeError:''int''对象没有属性''lower''


... print i
...
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/lib/python2.3/email/Message.py",
line 304, in __getitem__
File "/usr/lib/python2.3/email/Message.py",
line 370, in get
AttributeError: ''int'' object has no attribute ''lower''




- Paul



-- Paul


这篇关于没有__iter__的for循环文档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆