简体   繁体   English

无法迭代Python中的列表类

[英]Can't iterate over a list class in Python

I'm trying to write a simple GUI front end for Plurk using pyplurk. 我正在尝试使用pyplurk为Plurk编写一个简单的GUI前端。

I have successfully got it to create the API connection, log in, and retrieve and display a list of friends. 我已经成功地创建了API连接,登录,并检索并显示了一个朋友列表。 Now I'm trying to retrieve and display a list of Plurks. 现在我正在尝试检索并显示Plurks列表。

pyplurk provides a GetNewPlurks function as follows: pyplurk提供了一个GetNewPlurks函数,如下所示:

  def GetNewPlurks(self, since):
    '''Get new plurks since the specified time.
    Args:
      since: [datetime.datetime] the timestamp criterion.
    Returns:
      A PlurkPostList object or None.
    '''
    offset = jsonizer.conv_datetime(since)
    status_code, result = self._CallAPI('/Polling/getPlurks', offset=offset)
    return None if status_code != 200 else \
           PlurkPostList(result['plurks'], result['plurk_users'].values())

As you can see this returns a PlurkPostList, which in turn is defined as follows: 如您所见,这会返回一个PlurkPostList,后者又定义如下:

class PlurkPostList:
  '''A list of plurks and the set of users that posted them.'''
  def __init__(self, plurk_json_list, user_json_list=[]):
    self._plurks = [PlurkPost(p) for p in plurk_json_list]
    self._users = [PlurkUser(u) for u in user_json_list]
  def __iter__(self):
    return self._plurks
  def GetUsers(self):
    return self._users
  def __eq__(self, other):
    if other.__class__ != PlurkPostList: return False
    if self._plurks != other._plurks: return False
    if self._users != other._users: return False
    return True

Now I expected to be able to do something like this: 现在我希望能够做到这样的事情:

api = plurk_api_urllib2.PlurkAPI(open('api.key').read().strip(), debug_level=1)
plurkproxy = PlurkProxy(api, json.loads)
user = plurkproxy.Login('my_user', 'my_pass')
ps = plurkproxy.GetNewPlurks(datetime.datetime(2009, 12, 12, 0, 0, 0))
print ps
for p in ps:
  print str(p)

When I run this, what I actually get is: 当我运行它时,我实际得到的是:

<plurk.PlurkPostList instance at 0x01E8D738>

from the "print ps", then: 从“打印ps”,然后:

    for p in ps:
TypeError: __iter__ returned non-iterator of type 'list'

I don't understand - surely a list is iterable? 我不明白 - 肯定列表可迭代的? Where am I going wrong - how do I access the Plurks in the PlurkPostList? 我哪里错了 - 如何访问PlurkPostList中的Plurks?

When you define your own __iter__ method, you should realize that that __iter__ method should return an iterator , not an iterable . 当你定义自己的__iter__方法时,你应该意识到__iter__方法应该返回一个迭代器 ,而不是一个迭代器 You are returning a list, not an iterator to a list, so it fails. 您正在返回一个列表,而不是列表的迭代器,因此它失败了。 You can fix it by doing return iter(self._plurks) , for example. 例如,您可以通过return iter(self._plurks)来修复它。

If you wanted to do something a little more complex, like process each item in self._plurks as it's being iterated over, the usual trick is to make your __iter__ method be a generator . 如果你想做一些更复杂的事情,比如处理self._plurks中的每个项目,因为它被迭代,通常的技巧是让你的__iter__方法成为一个生成器 That way, the returnvalue of the call to __iter__ is the generator, which is an iterator: 这样,对__iter__的调用的返回值是生成器,它是一个迭代器:

def __iter__(self):
    for item in self._plurks:
        yield process(item)

The __iter__ method should return an object which implements the next() method. __iter__方法应该返回一个实现next()方法的对象。

A list does not have a next() method, but it has an __iter__ method, which returns a listiterator object. 列表没有next()方法,但它有一个__iter__方法,它返回一个listiterator对象。 The listiterator object has a next() method. listiterator对象有一个next()方法。

You should write: 你应该写:

def __iter__(self):
    return iter(self._plurks)

As an alternative, you can also define the next() function and have __iter__() return self. 作为替代方案,您还可以定义next()函数并让__iter__()返回self。 See Build a Basic Python Iterator for a nice example. 请参阅构建基本Python迭代器以获得一个很好的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM