Не могу перебрать класс списка в Python - PullRequest
6 голосов
/ 16 апреля 2010

Я пытаюсь написать простой интерфейс для Plurk с использованием pyplurk.

Я успешно получил его, чтобы создать соединение API, войти в систему, а также получить и отобразить список друзей. Сейчас я пытаюсь получить и отобразить список Plurks.

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())

Как вы можете видеть, это возвращает 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

Теперь я ожидал, что смогу сделать что-то вроде этого:

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)

Когда я запускаю это, я на самом деле получаю:

<plurk.PlurkPostList instance at 0x01E8D738>

из "print ps", затем:

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

Я не понимаю - конечно, список повторяем? Где я ошибаюсь - как мне получить доступ к Plurks в PlurkPostList?

Ответы [ 3 ]

14 голосов
/ 16 апреля 2010

Когда вы определяете свой собственный метод __iter__, вы должны понимать, что метод __iter__ должен возвращать итератор , а не итеративный . Вы возвращаете список, а не итератор, поэтому он не работает. Вы можете исправить это, например, return iter(self._plurks).

Если вы хотите сделать что-то немного более сложное, например, обработать каждый элемент в self._plurks во время его итерации, обычная уловка - сделать ваш __iter__ метод генератором . Таким образом, возвращаемое значение вызова __iter__ является генератором, который является итератором:

def __iter__(self):
    for item in self._plurks:
        yield process(item)
5 голосов
/ 16 апреля 2010

Метод __iter__ должен возвращать объект, который реализует метод next().

В списке нет метода next(), но есть метод __iter__, который возвращает объект listiterator. У объекта listiterator есть метод next().

Вы должны написать:

def __iter__(self):
    return iter(self._plurks)
0 голосов
/ 16 апреля 2010

В качестве альтернативы, вы также можете определить функцию next() и заставить __iter__() вернуть себя. См. Создание базового итератора Python для хорошего примера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...