Можно ли определить метод __iter__ для класса? [Дубликат]

Идентификаторы могут использоваться только один раз в документе, и они должны быть уникальными. Вместо этого вы создаете класс, а затем нацеливаете этот класс и запускаете функцию для каждого элемента с этим классом.

Пример дайте им класс = "vid"

<script>

var videos = document.getElementsByClassName('vid');
// When the 'ended' event fires


for (var i = 0; i < videos.length; i++) {
    videos[i].addEventListener('ended', function(){
    // Reset the video to 
    videos[i].currentTime = 0;
    // And play again
    videos[i].load();
   });
}

</script>

Я не уверен, что этот точный код работает с добавлением слушателя событий, но концепция правильная.

32
задан eat 25 March 2011 в 16:29
поделиться

5 ответов

Добавить __iter__ в метакласс вместо самого класса (предполагая Python 2.x):

class Foo(object):
    bar = "bar"
    baz = 1
    class __metaclass__(type):
        def __iter__(self):
            for attr in dir(Foo):
                if not attr.startswith("__"):
                    yield attr

Для Python 3.x используйте

class MetaFoo(type):
    def __iter__(self):
        for attr in dir(Foo):
            if not attr.startswith("__"):
                yield attr

class Foo(metaclass=MetaFoo):
    bar = "bar"
    baz = 1
49
ответ дан Sven Marnach 21 August 2018 в 15:35
поделиться
  • 1
    Ницца. Пожалуйста, не могли бы вы объяснить, почему подход OP не работает? Благодарю. – NPE 25 March 2011 в 16:25
  • 2
    @aix: Причина подхода OP не работает, так как метод __iter__ работает только для экземпляров класса. Это сравнивает метод __iter__ до экземпляров метакласса, т. Е. Класса. – nmichaels 25 March 2011 в 16:41
  • 3
    @nmichaels Это имеет смысл, спасибо за объяснение. – NPE 25 March 2011 в 16:42
  • 4
    @aix: Как другие магические методы, __iter__ просматривается в пространстве имен типа объекта, а не в самом пространстве имен объекта. Я действительно не нашел это объясненным в документах Python, но его можно легко увидеть в исходном коде (найдите определение PyObject_GetIter()). – Sven Marnach 25 March 2011 в 16:52
  • 5
    @trudolf: Специальные методы проверяются на тип экземпляра, а не на сам экземпляр . Если экземпляр является классом, это означает, что специальный метод просматривается на метаклассе, а не на самом классе. – Sven Marnach 24 June 2015 в 13:04

Как и в случае с Python 3.4+, создание итерации класса немного проще с помощью enum.Enum .

from enum import Enum

class Foo(Enum):
    bar = "qux"
    baz = 123

>>> print(*Foo)
Foo.bar Foo.baz

names = [m.name for m in Foo]
>>> print(*names)
bar baz

values = [m.value for m in Foo]
print(*values)
>>> qux 123
1
ответ дан A-B-B 21 August 2018 в 15:35
поделиться

Вы можете перебирать невидимые атрибуты класса с помощью for attr in (elem for elem in dir(Foo) if elem[:2] != '__').

Менее ужасный способ написания:

def class_iter(Class):
    return (elem for elem in dir(Class) if elem[:2] != '__')

, затем

for attr in class_iter(Foo):
    pass
7
ответ дан nmichaels 21 August 2018 в 15:35
поделиться
  • 1
    Должен признаться, я предпочитаю это решение, которое выглядит более питоническим, чем одно из OP. Но разве это не решение его проблемы, я не сделал +1 – Xavier Combelle 25 March 2011 в 16:38
class MetaItetaror(type):
    def __iter__(cls):
        return iter(
            filter(
                lambda k: not k[0].startswith('__'),
                cls.__dict__.iteritems()
            )
        )


class Klass:
    __metaclass__ = MetaItetaror

    iterable_attr_names = {'x', 'y', 'z'}
    x = 5
    y = 6
    z = 7


for v in Klass:
    print v
0
ответ дан sanit 21 August 2018 в 15:35
поделиться

это то, как мы делаем объект класса итерабельным. предоставить класс с помощью метода iter и next (), тогда вы можете перебирать атрибуты класса или их значения. Вы можете оставить метод next (), если хотите, или вы можете определить next () и повысить StopIteration при некотором условии .

например:

class Book(object):
      def __init__(self,title,author):
          self.title = title
          self.author = author

      def __iter__(self):
          for each in self.__dict__.keys():
              yield self.__getattribute__(each)

>>> book  = Book('The Mill on the Floss','George Eliot')
>>> for each in book: each
...
'George Eliot'
'The Mill on the Floss'

этот класс выполняет итерацию над значением атрибута класса Book. Объект класса можно сделать итерабельным, предоставив ему метод getitem. например:

class BenTen(object):
    def __init__(self, bentenlist):
        self.bentenlist = bentenlist

    def __getitem__(self,index):
        if index <5:
            return self.bentenlist[index]
        else:
            raise IndexError('this is high enough')

>>> bt_obj = BenTen([x for x in range(15)])
>>>for each in bt_obj:each
...
0
1
2
3
4

теперь, когда объект класса BenTen используется во внутреннем цикле, getitem вызывается с успешным более высоким значением индекса, пока он не вызовет IndexError.

7
ответ дан vijay shanker 21 August 2018 в 15:35
поделиться
  • 1
    Это повторяется по атрибутам экземпляра класса (т. Е. book в book = Book(...)); возникает вопрос об итерации по атрибутам class непосредственно (т. е. Book в class Book(object):). – multipleinterfaces 2 January 2013 в 17:45
  • 2
    Хотя это не ответ на вопрос OP, это помогло мне, потому что я искал это при поиске итерируемого класса. – dlite922 22 March 2013 в 20:04
Другие вопросы по тегам:

Похожие вопросы: