Я вижу несколько вещей, чтобы быть улучшены в коде от вопроса , Во-первых, цикл while
редко используется в Python, потому что почти всегда есть лучший способ выразить то же самое с помощью цикла for
или с использованием некоторых встроенных функций.
Я предполагаю, что код предназначен исключительно для тренировочной цели. В противном случае я бы спросил сначала, какова реальная цель (потому что, зная проблему, лучшее решение может сильно отличаться от первой идеи).
Целью является получение позиций для seek
. Вы знаете размер, вы знаете размер куска, вы хотите вернуться назад. Для Python имеется встроенный генератор с именем range
. В основном используется один аргумент; однако, range(start, stop, step)
- полная форма. Генератор может быть итерирован в цикле for
, или вы можете использовать значения, чтобы построить их список (но часто вам не нужен более поздний случай). Позиции для seek
могут быть получены следующим образом:
chunk = 10
sz = 235
lst = list(range(sz - chunk, 0, -chunk))
print(lst)
Т.е., вы начинаете с sz - chunk
позиции, остановка в нуле (не часто), используя отрицательное значение для следующего сгенерированного значения. Здесь list()
выполняет итерацию по всем значениям и строит их список. Но вы можете выполнять итерацию напрямую через сгенерированные значения:
for pos in range(sz - chunk, 0, -chunk):
print('seek({}) and read({})'.format(pos, chunk))
if pos > 0:
print('seek({}) and read({})'.format(0, pos))
Последнее сгенерированное положение равно нулю или положительно. Таким образом, последний if
обрабатывает последнюю часть, когда она меньше, чем chunk
. Положив выше код вместе, он печатает:
c:\tmp\_Python\wikicsm\so16443185>py a.py
[225, 215, 205, 195, 185, 175, 165, 155, 145, 135, 125, 115, 105, 95,
85, 75, 65, 55, 45, 35, 25, 15, 5]
seek(225) and read(10)
seek(215) and read(10)
seek(205) and read(10)
seek(195) and read(10)
seek(185) and read(10)
seek(175) and read(10)
seek(165) and read(10)
seek(155) and read(10)
seek(145) and read(10)
seek(135) and read(10)
seek(125) and read(10)
seek(115) and read(10)
seek(105) and read(10)
seek(95) and read(10)
seek(85) and read(10)
seek(75) and read(10)
seek(65) and read(10)
seek(55) and read(10)
seek(45) and read(10)
seek(35) and read(10)
seek(25) and read(10)
seek(15) and read(10)
seek(5) and read(10)
seek(0) and read(5)
лично я бы заменить print
«S, вызывая функцию, которая будет принимать файл объекта, поз и размер порции.Здесь подделать тело, чтобы произвести те же отпечатки:
#!python3
import os
def processChunk(f, pos, chunk_size):
print('faked f: seek({}) and read({})'.format(pos, chunk_size))
fname = 'a.txt'
sz = os.path.getsize(fname) # not checking existence for simplicity
chunk = 16
with open(fname, 'rb') as f:
for pos in range(sz - chunk, 0, -chunk):
processChunk(f, pos, chunk)
if pos > 0:
processChunk(f, 0, pos)
with
конструкция является еще один хорошо учиться. (Предупреждение, ничего похожего на Pascal's with
.) Он автоматически закрывает объект файла после завершения блока. Обратите внимание, что код ниже with
является более читаемым и не нуждается в дальнейшем изменении. processChunk
будет развиваться дальше:
def processChunk(f, pos, chunk_size):
f.seek(pos)
s = binascii.hexlify(f.read(chunk_size))
print(s)
или вы можете изменить его немного, так что его результат перевернутую шестнадцатеричного (полный код протестирован на моем компьютере):
#!python3
import binascii
import os
def processChunk(f, pos, chunk_size):
f.seek(pos)
b = f.read(chunk_size)
b1 = b[:8] # first 8 bytes
b2 = b[8:] # the rest
s1 = ' '.join('{:02x}'.format(x) for x in b1)
s2 = ' '.join('{:02x}'.format(x) for x in b2)
print('{:08x}:'.format(pos), s1, '|', s2)
fname = 'a.txt'
sz = os.path.getsize(fname) # not checking existence for simplicity
chunk = 16
with open(fname, 'rb') as f:
for pos in range(sz - chunk, 0, -chunk):
processChunk(f, pos, chunk)
if pos > 0:
processChunk(f, 0, pos)
Когда a.txt
является копией последнего кода, он производит:
c:\tmp\_Python\wikicsm\so16443185>py d.py
00000274: 75 6e 6b 28 66 2c 20 30 | 2c 20 70 6f 73 29 0d 0a
00000264: 20 20 20 20 20 20 20 70 | 72 6f 63 65 73 73 43 68
00000254: 20 20 69 66 20 70 6f 73 | 20 3e 20 30 3a 0d 0a 20
00000244: 6f 73 2c 20 63 68 75 6e | 6b 29 0d 0a 0d 0a 20 20
00000234: 72 6f 63 65 73 73 43 68 | 75 6e 6b 28 66 2c 20 70
00000224: 75 6e 6b 29 3a 0d 0a 20 | 20 20 20 20 20 20 20 70
00000214: 20 2d 20 63 68 75 6e 6b | 2c 20 30 2c 20 2d 63 68
00000204: 20 70 6f 73 20 69 6e 20 | 72 61 6e 67 65 28 73 7a
000001f4: 61 73 20 66 3a 0d 0a 0d | 0a 20 20 20 20 66 6f 72
000001e4: 65 6e 28 66 6e 61 6d 65 | 2c 20 27 72 62 27 29 20
000001d4: 20 3d 20 31 36 0d 0a 0d | 0a 77 69 74 68 20 6f 70
000001c4: 69 6d 70 6c 69 63 69 74 | 79 0d 0a 63 68 75 6e 6b
000001b4: 20 65 78 69 73 74 65 6e | 63 65 20 66 6f 72 20 73
000001a4: 20 20 23 20 6e 6f 74 20 | 63 68 65 63 6b 69 6e 67
00000194: 65 74 73 69 7a 65 28 66 | 6e 61 6d 65 29 20 20 20
00000184: 0d 0a 73 7a 20 3d 20 6f | 73 2e 70 61 74 68 2e 67
00000174: 0a 66 6e 61 6d 65 20 3d | 20 27 61 2e 74 78 74 27
00000164: 31 2c 20 27 7c 27 2c 20 | 73 32 29 0d 0a 0d 0a 0d
00000154: 27 2e 66 6f 72 6d 61 74 | 28 70 6f 73 29 2c 20 73
00000144: 20 20 70 72 69 6e 74 28 | 27 7b 3a 30 38 78 7d 3a
00000134: 66 6f 72 20 78 20 69 6e | 20 62 32 29 0d 0a 20 20
00000124: 30 32 78 7d 27 2e 66 6f | 72 6d 61 74 28 78 29 20
00000114: 32 20 3d 20 27 20 27 2e | 6a 6f 69 6e 28 27 7b 3a
00000104: 20 78 20 69 6e 20 62 31 | 29 0d 0a 20 20 20 20 73
000000f4: 7d 27 2e 66 6f 72 6d 61 | 74 28 78 29 20 66 6f 72
000000e4: 20 27 20 27 2e 6a 6f 69 | 6e 28 27 7b 3a 30 32 78
000000d4: 65 20 72 65 73 74 0d 0a | 20 20 20 20 73 31 20 3d
000000c4: 20 20 20 20 20 20 20 20 | 20 20 20 20 23 20 74 68
000000b4: 62 32 20 3d 20 62 5b 38 | 3a 5d 20 20 20 20 20 20
000000a4: 73 74 20 38 20 62 79 74 | 65 73 0d 0a 20 20 20 20
00000094: 20 20 20 20 20 20 20 20 | 20 20 20 23 20 66 69 72
00000084: 31 20 3d 20 62 5b 3a 38 | 5d 20 20 20 20 20 20 20
00000074: 75 6e 6b 5f 73 69 7a 65 | 29 0d 0a 20 20 20 20 62
00000064: 20 20 20 62 20 3d 20 66 | 2e 72 65 61 64 28 63 68
00000054: 20 20 66 2e 73 65 65 6b | 28 70 6f 73 29 0d 0a 20
00000044: 63 68 75 6e 6b 5f 73 69 | 7a 65 29 3a 0d 0a 20 20
00000034: 73 73 43 68 75 6e 6b 28 | 66 2c 20 70 6f 73 2c 20
00000024: 20 6f 73 0d 0a 0d 0a 64 | 65 66 20 70 72 6f 63 65
00000014: 62 69 6e 61 73 63 69 69 | 0d 0a 69 6d 70 6f 72 74
00000004: 74 68 6f 6e 33 0d 0a 0d | 0a 69 6d 70 6f 72 74 20
00000000: 23 21 70 79 |
Для src_file_path = 'd:\\src\\python\\test\\main.zip'
, вы можете использовать прямую косую черту, как src_file_path = 'd:/src/python/test/main.zip'
также в Windows. Или вы можете использовать необработанные строки как src_file_path = r'd: \ src \ python \ test \ main.zip '. Последний случай используется, когда вам нужно избегать удвоения обратных косых черт - часто при написании регулярных выражений.
Спасибо за ваши комментарии, pepr. Для меня ваше мнение ценно, я постараюсь перестать использовать 'while'. К сожалению, это не для обучения, я хочу написать программу, имитирующую поведение моего алгоритма. Выберите язык Python из-за его ясности и широкой поддержки. Но поскольку я новичок, Я смотрю на все образцы кода, глаза широко открытые, даже пугающие порой :). – 2013-05-08 17:02:04
В течение трех дней я уже хорошо переехал - я знаю, как читать файл, обрабатывать его и записывать обратно в файл. Осталось так мало - соединить все мелкие объекты в один ... Конструкция 'for pos в диапазоне (sz - chunk, 0, -chunk):' Мне понравилось, это интуитивно. Еще раз спасибо за ваш комментарий. – 2013-05-08 17:02:31
Если цикл 'while' должен использоваться, тогда я рекомендую переименовать' src_file_size' в 'pos'. Затем вы заметите ошибку в 'while pos> 0:'. На самом деле нулевое значение также должно приниматься (т. Е. '> = 0'). – pepr