Python 3.6. Чем заменить walrus оператор
Скрипт принимает на вход путь с файлами и сравнивает их между собой по хеш-сумме. Ну а чтобы сильно не грузить оперативную память, принято решение резать файлы на кусочки.
Есть проблема. Walrus. В python 3.8 все отлично, но для python 3.6 работать не будет (3.6 не поддерживает walrus). Чем заменить конструкцию while chunk := f.read(8192)?
def identical_video_by_hash(file_path):
video_hash_name_dict = {}
for file in Path(file_path).glob(r"**/*"):
if file.suffix.casefold() in file_ext:
with open(video, "rb") as f:
file_hash = hashlib.md5()
while chunk := f.read(8192):
file_hash.update(chunk)
video_hash_name_dict[str(file)] = file_hash.hexdigest()
Ответы (2 шт):
Этот способ допустим?
def identical_video_by_hash(video_path):
video_hash_name_dict = {}
for video in Path(video_path).glob(r"**/*"):
if video.suffix.casefold() in video_ext:
with open(video, "rb") as f:
file_hash = hashlib.md5()
while True:
chunk = f.read(8192)
if not chunk:
break
file_hash.update(chunk)
video_hash_name_dict[str(video)] = file_hash.hexdigest()
В данном случае можно использовать функцию iter с двумя параметрами: с функцией (которая при каждом запросе считывает и возвращает новый блок данных) и признаком окончания итерации (значение, которое должна вернуть функция, переданная в первом параметре, чтобы итерация прекратилась, в документации называется "sentinel" - "стражник"). В данном случае итерация должна прекратиться, когда вернется пустой блок (b''). Функция iter возвращает итератор, его можно использовать в конструкции for.
with open(video, "rb") as f:
file_hash = hashlib.md5()
for chunk in iter(lambda: f.read(8192), b''):
file_hash.update(chunk)
Документация: iter (там как раз приведен пример для такой задачи)