Следующие работы в Firefox и Opera (извините, у меня нет доступа к другим браузерам в данный момент):
<div class="form-field">
<input id="option1" type="radio" name="opt"/>
<label for="option1">Option 1</label>
</div>
CSS:
.form-field * {
vertical-align: middle;
}
Итератору необходимо определить два метода: __ iter __ ()
и __ next __ ()
( next ()
в python2) . Обычно сам объект определяет метод __ next __ ()
или next ()
, поэтому он просто возвращает себя как итератор. Это создает итератор , который также является итератором . Эти методы используются для
и в
операторах.
Документы Python 3: docs.python.org/3/library/stdtypes.html#iterator-types
Документы Python 2: docs.python.org/2/library/stdtypes.html#iterator-types
Спецификации для def __iter __ (self):
таковы: он возвращает итератор. Итак, если self
является итератором, return self
явно подходит.
«Быть итератором» означает «иметь метод __ next __ (self)
» (в Python 3; в Python 2 имя рассматриваемого метода, к сожалению, простое next
, а это явно ошибка дизайна имени для специального метода).
В Python 2.6 и выше лучший способ реализации итератора, как правило, заключается в использовании соответствующего абстрактного базового класса из модуля collections
стандартной библиотеки - в Python 2.6 код может быть (не забудьте вызвать метод ] __ next __
вместо Python 3):
import collections
class infinite23s(collections.Iterator):
def next(self): return 23
экземпляр этого класса будет возвращать бесконечно много копий 23
при повторении (например, itertools.repeat (23)
), поэтому в противном случае цикл должен быть завершен. Дело в том, что создание подкласса collections.Iterator
добавляет правильный метод __ iter __
от вашего имени - здесь нет ничего страшного, но хороший общий принцип (избегайте повторяющегося шаблонного кода, такого как итераторы) стандартная однострочная __ iter __
- повторюсь, здесь нет добавленной стоимости и много вычитаемой стоимости! -).
В Python итератором является любой объект, поддерживающий протокол итератора. Частью этого протокола является то, что объект должен иметь метод __ iter __ ()
, который возвращает объект-итератор. Я полагаю, это дает вам некоторую гибкость, так что объект может передать обязанности итератора внутреннему классу или создать какой-то специальный объект. В любом случае, метод __ iter __ ()
обычно имеет только одну строку, и эта строка часто просто return self
Другая часть протокола - это next ()
, и именно здесь выполняется настоящая работа. Этот метод должен выяснить, создать или получить следующую вещь и вернуть ее. Возможно, ему потребуется отслеживать, где он находится, чтобы при следующем вызове он действительно возвращал следующее.
Когда у вас есть объект, который возвращает следующее в последовательности, вы можете свернуть цикл for, который выглядит следующим образом:
myname = "Fredericus"
x = []
for i in [1,2,3,4,5,6,7,8,9,10]:
x.append(myname[i-1])
i = i + 1 # get the next i
print x
в этот:
myname = "Fredericus"
x = [myname[i] for i in range(10)]
print x
Обратите внимание, что нигде нет кода, который получает следующий значение i, потому что диапазон (10) - это объект, СЛЕДУЮЩИЙ за протоколом итератора, а понимание списка - это конструкция, которая ИСПОЛЬЗУЕТ протокол итератора.
Вы также можете ИСПОЛЬЗОВАТЬ протокол итератора напрямую. Например, при написании сценариев для обработки файлов CSV я часто пишу следующее:
mydata = csv.reader(open('stuff.csv')
mydata.next()
for row in mydata:
# do something with the row.
Я использую итератор напрямую, вызывая next ()
, чтобы пропустить строку заголовка, а затем использую его косвенно через встроенный в операторе
в операторе for
.
myname = "Fredericus"
x = [myname[i] for i in range(10)]
print x
Обратите внимание, что нигде у нас нет кода, который получает следующее значение i, потому что диапазон (10) - это объект, СЛЕДУЮЩИЙ протоколу итератора, а понимание списка - это конструкция, которая ИСПОЛЬЗУЕТ протокол итератора.
Вы также может ИСПОЛЬЗОВАТЬ протокол итератора напрямую. Например, при написании сценариев для обработки файлов CSV я часто пишу следующее:
mydata = csv.reader(open('stuff.csv')
mydata.next()
for row in mydata:
# do something with the row.
Я использую итератор напрямую, вызывая next ()
, чтобы пропустить строку заголовка, а затем использую его косвенно через встроенный в операторе
в операторе for
.
myname = "Fredericus"
x = [myname[i] for i in range(10)]
print x
Обратите внимание, что нигде у нас нет кода, который получает следующее значение i, потому что диапазон (10) - это объект, СЛЕДУЮЩИЙ протоколу итератора, а понимание списка - это конструкция, которая ИСПОЛЬЗУЕТ протокол итератора.
Вы также может ИСПОЛЬЗОВАТЬ протокол итератора напрямую. Например, при написании сценариев для обработки файлов CSV я часто пишу следующее:
mydata = csv.reader(open('stuff.csv')
mydata.next()
for row in mydata:
# do something with the row.
Я использую итератор напрямую, вызывая next ()
, чтобы пропустить строку заголовка, а затем использую его косвенно через встроенный в операторе
в операторе for
.
Класс, поддерживающий метод __iter__, вернет экземпляр объекта итератора: объект, поддерживающий метод next () . Этот объект будет использоваться в операторах «for» и «in».
Как я могу выразиться просто:
__ iter __
определяет метод класса, который будет возвращать итератор (объект, который последовательно выдает следующий элемент, содержащийся в вашем объекте) .
Объект итератора, который возвращает __ iter __ ()
, может быть практически любым объектом, если он определяет метод next ()
.
next Метод
будет вызываться операторами типа for ... in ...
для перехода к следующему элементу, а next ()
должен вызывать исключение StopIteration
, когда больше нет элементов.
Что в этом хорошего, так это то, что он позволяет вам ] определяют способ итерации вашего объекта, а __ iter __
предоставляет общий интерфейс, с которым знает, как работать любая другая функция python.