Фильтр tarfile в Python 3.7

1

Это часть моего сценария резервного копирования, который я разделил для тестирования. Это использовалось для работы в python 3.6, но я получаю ошибки в python 3.7. Я проверил документы, но не могу понять, что изменилось.

#! /usr/bin/python

import os
import tarfile
import arrow


stmp = arrow.now().format('YYYY-MM-DD')
backup_path = "/home/akya/playground/"

###########################################################
# Functions
###########################################################

def exclude_function(filename):
    if filename in exclude_files or os.path.splitext(filename)[1] in exclude_files:
        return True
    else:
        return False

def compress():
    with tarfile.open(myfile, "w:gz") as tar:
        for name in L:
            tar.add(name, filter=exclude_function)

path1 = "/home/akya/playground/test"
backup_name = "test-"

L = [path1]
exclude_files = [".sh", ".html", ".json", "/home/akya/playground/test/.git"]
myfile = str(backup_path + backup_name + stmp + ".tar.gz")

compress()

Я хочу, чтобы tarfile исключал любые расширения и пути в exclude_files. и это то, что я получаю

Traceback (most recent call last):
  File "exec.py", line 33, in <module>
    compress()
  File "exec.py", line 24, in compress
    tar.add(name, filter=exclude_function)
  File "/usr/lib/python3.7/tarfile.py", line 1934, in add
    tarinfo = filter(tarinfo)
  File "exec.py", line 16, in exclude_function
    if filename in exclude_files or os.path.splitext(filename)[1] in exclude_files:
  File "/usr/lib/python3.7/posixpath.py", line 122, in splitext
    p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not TarInfo

Может ли кто-нибудь указать на необходимость изменения? или лучший способ использования фильтров?

Теги:
python-3.7
tarfile

1 ответ

2
Лучший ответ

Обратный вызов filter передает структуру TarInfo вашему TarInfo вызову, поэтому вы можете фильтровать что-то другое, кроме имени: дата, размер, время модификации (очень похоже на объект stat)...

Кроме того, это не работает (возвращая логические значения), вы должны вернуть None если хотите исключить эту запись:

TarFile.add(name, arcname = None, recursive = True, *, filter = None)

... Если задан фильтр, он должен быть функцией, которая принимает аргумент объекта TarInfo и возвращает измененный объект TarInfo. Если он вместо этого возвращает None, объект TarInfo будет исключен из архива. См. Примеры для примера.

В вашем случае просто выберите поле .name и верните None если это соответствует вашему фильтру. Else возвращает ту же структуру tarinfo вы получили.

def exclude_function(tarinfo):
    filename = tarinfo.name
    return None if filename in exclude_files or os.path.splitext(filename)[1] in exclude_files else tarinfo

(обратите внимание, что я не знаю, почему это сработало для вас в более ранних версиях, возможно, вы добавили это or os.path.splitext(filename)[1] in exclude_files что показывает, что тип неверен - первый in тесте wouldn ' t сбой даже с объектом неправильного типа - но это правильный способ сделать это)

  • 0
    Спасибо, теперь я понимаю это лучше.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню