Заявление о выходе Python, по-видимому, не продолжается с того места, на котором оно было остановлено - PullRequest
4 голосов
/ 10 июня 2011

Я, должно быть, упускаю из виду очевидное, но я не могу до конца жизни понять, почему это заявление о доходности не дает мне постоянно новое значение даты и времени, которое на 15 минут позже предыдущего. Функция gettime ведет себя больше как функция, которая «возвращает», а не «возвращает».

import datetime

#function that continually adds 15 minutes to a datetime object
def gettime(caldate):
    while True:
        yield caldate
        caldate += datetime.timedelta(minutes=15)

#initialize a datetime object
nextdate = datetime.datetime(2011, 8, 22, 11,0,0,0)

#call gettime function 25 times.
for i in range(0,25):
    print gettime(nextdate).next()


#output feels like it should be a series of incrementing datetime values 15 minutes apart.
#in actuality, the same result namely:

#2011-08-22 11:00:00

#happens 25 times.

Ответы [ 3 ]

15 голосов
/ 10 июня 2011

Это потому, что вы каждый раз вызываете генератор, запускаете его заново.

Вот исправленная версия:

dates = gettime(nextdate)
for i in range(0, 25):
    print dates.next()   # note that you're not initializing it each time here
                         # just calling next()

Это дает мне:

2011-08-22 11:00:00
2011-08-22 11:15:00
2011-08-22 11:30:00
2011-08-22 11:45:00
...etc.

Важно помнить, что функция, которая на самом деле yield s возвращает генератор , как вы можете видеть, когда мы смотрим на мой dates объект:

>>> dates
<generator object gettime at 0x02A05710>

Это то, что вы можете неоднократно вызывать next(), чтобы получить следующее значение. Каждый раз, когда вы выполняли свой цикл, вы создавали совершенно новый генератор и извлекали из него следующее (в данном случае первое) значение.

3 голосов
/ 10 июня 2011

Даниэль уже указал, что вы создаете новый генератор каждый раз через свой цикл. Более обычным является обход цикла генератора или его использование другим генератором, чем явный вызов next() каждый раз.

Вот как вы можете зациклить островок () вашего генератора.

from itertools import islice
import datetime

#generator that continually adds 15 minutes to a datetime object
def gettime(caldate):
    while True:
        yield caldate
        caldate += datetime.timedelta(minutes=15)

#initialize a datetime object
nextdate = datetime.datetime(2011, 8, 22, 11,0,0,0)

#call gettime function 25 times.
for the_date in islice(gettime(nextdate),0,25):
    print the_date

Вы также можете упростить это до выражения генератора, если хотите

from itertools import islice, count
import datetime

#initialize a datetime object
nextdate = datetime.datetime(2011, 8, 22, 11,0,0,0)

#generator expression that continually adds 15 minutes to a datetime object
gettime = (nextdate+datetime.timedelta(minutes=15*i) for i in count())

#call gettime function 25 times.
for the_date in islice(gettime,0,25):
    print the_date
0 голосов
/ 10 июня 2011

Использование функции print_:

print(*[i[0] for i in zip(gettime(nextdate), range(25))], sep='\n')

Но вы можете иметь только список.

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