Предупреждение о закрытом файле в Python - PullRequest
1 голос
/ 12 марта 2019

Я написал следующий код:

class LazyPackageLoader:
    def __init__(self, package_names):
        self.package_names = package_names

    def install_packages(self):
        try:
            cache = apt.cache.Cache()
            cache.update()
            cache.open()

            for package in self.package_names:
                pkg = cache[package]
                pkg.mark_install()

            cache.commit()

        except Exception as e:
            print (str(e))

        finally:
            cache.close()

    def show_all_packages(self):
        pkgs = list()
        cache = apt.Cache()

        for package in cache:
            if cache[package.name].is_installed:
                pkgs.append(package.name)

        cache.close()
        return pkgs

Я называю это так:

class TestLazyPackageLoader(unittest.TestCase):
    def test_installed_package(self):
        packagelist = list()
        packagelist.append("ethtool")

        lpl = LazyPackageLoader(packagelist)
        lpl.install_packages()

        packages = lpl.show_all_packages()
        if "ethtool" in packages:
            self.assertEqual(True, True)


if __name__ == '__main__':
    unittest.main()

Код работает, как и ожидалось, однако я получаю следующие предупреждения:

ResourceWarning: открытый файл <_io.TextIOWrapper name = 44 mode = 'w' encoding = 'UTF-8'> cache.commit

ResourceWarning: открытый файл <_io.TextIOWrapper name= 43 mode = 'r' encoding = 'UTF-8'> cache.commit ()

Полагаю, предупреждение достаточно простое: существует неоткрытый файл, который в конечном итоге закрывается Python.

Я читал об этом и думаю, что мне следует обернуть код в оператор 'with', что достаточно просто для чтения простого текстового файла, но я не могу понять, как это сделатьэто с этой библиотекой.Я думаю, что наиболее существенный вызов здесь - cache.close, который, как я думал, обязательно будет выполнен, когда будет вызван finally.

1 Ответ

2 голосов
/ 12 марта 2019

Быстрый обзор в репозитории python-apt показал, что класс apt.cache.Cache() реализует два метода, необходимых для ключевого слова with, то есть __enter__() и __exit__().

Что означает, что вам просто нужно сделать:

with apt.cache.Cache() as c:
   # ... do your things with c ...

# here, c is closed 

Пример из вашего кода:

def show_all_packages(self):
    with apt.cache.Cache() as cache:
        return [package.name for package in cache if cache[package.name].is_installed]
...