"Отладка" и "Выпуск" являются просто названиями предопределенных конфигураций проекта, определенных Visual Studio.
Для наблюдения различий посмотрите на Вкладку Сборки в Свойствах проекта в Visual Studio.
различия в VS2005 включают:
ОТЛАЖИВАЮТ постоянный определенный в Настройке отладочного процесса
, Оптимизируют код, включенный в конфигурации Выпуска
, а также другие различия, которые Вы видите путем нажатия на кнопку
"Advanced", Но Вы можете:
Изменяют настройки сборки для конфигураций Отладки и Выпуска в Propeties Проекта / Сборка
Создает Ваши собственные конфигурации путем щелчка правой кнопкой по решению в Проводнике Решения, и выбирая Менеджер конфигурации
я думаю, что поведение постоянной ОТЛАДКИ довольно ясно (может быть сослан в #if директиве препроцессору или в ConditionalAttribute). Но я не знаю ни о какой подробной документации относительно точно, какая оптимизация включена - на самом деле я подозреваю, что Microsoft хотела бы быть свободной улучшить их оптимизатор без уведомления
Вы можете комбинировать итерацию через iter () с дозорным:
for block in iter(lambda: file_obj.read(4), ""):
use(block)
Вы видели, как перебирать строки в текстовом файле?
for line in file_obj:
use(line)
Вы можете сделать то же самое с вашим собственным генератором:
def read_blocks(file_obj, size):
while True:
data = file_obj.read(size)
if not data:
break
yield data
for block in read_blocks(file_obj, 4):
use(block)
См. Также:
Маркер EOF в python - это пустая строка, так что то, что у вас есть, довольно близко к тому лучшему, что вы собираетесь получить без написания функции, которая завершает это в итераторе. Я мог бы быть написан немного более питоническим способом, изменив while
, например:
while len_name:
len_name = struct.unpack("<I", len_name)[0]
names.append(data.read(len_name))
len_name = data.read(4)
Я предпочитаю уже упомянутое решение на основе итератора, чтобы превратить его в -петля. Другое решение, написанное непосредственно, - это «полтора цикла» Кнута
while 1:
len_name = data.read(4)
if not len_name:
break
names.append(data.read(len_name))
. Вы можете увидеть, сравнивая, как его легко поднять в собственный генератор и использовать в качестве цикла for.
Я бы выбрал функцию повторного предложения и итератор Tendayi для удобства чтения:
def read4():
len_name = data.read(4)
if len_name:
len_name = struct.unpack("<I", len_name)[0]
return data.read(len_name)
else:
raise StopIteration
for d in iter(read4, ''):
names.append(d)
Я вижу, как и предсказывалось, что типичный и самый популярный ответ - использование очень специализированных генераторов для «чтения 4 байтов за раз». Иногда универсальность не сложнее (и намного полезнее ;-), поэтому я предложил вместо этого следующее очень общее решение:
import operator
def funlooper(afun, *a, **k):
wearedone = k.pop('wearedone', operator.not_)
while True:
data = afun(*a, **k)
if wearedone(data): break
yield data
Теперь ваш желаемый заголовок цикла просто: для len_name в funlooper (data. читать, 4):
.
Править : сделанное гораздо более общим с помощью идиомы wearedone
, поскольку комментарий обвинял мою немного менее общую предыдущую версию (жесткое кодирование теста выхода как , если не данные:
) в "скрытой зависимости", в все! -)
Обычный швейцарский армейский нож для петель, itertools
, тоже хорош, конечно, как обычно:
import itertools as it
for len_name in it.takewhile(bool, it.imap(data.read, it.repeat(4))): ...
или, что эквивалентно:
import itertools as it
def loop(pred, fun, *args):
return it.takewhile(pred, it.starmap(fun, it.repeat(args)))
for len_name in loop(bool, data.read, 4): ...