Я бы рекомендовал использовать with
оператор Python для управления ресурсами, которые необходимо очистить. Проблема с использованием явного close()
выражения состоит в том, что вам нужно беспокоиться о людях, которые вообще не будут вызывать его или забывают поместить его в finally
блок, чтобы предотвратить утечку ресурсов при возникновении исключения.
Чтобы использовать with
оператор, создайте класс с помощью следующих методов:
def __enter__(self)
def __exit__(self, exc_type, exc_value, traceback)
В вашем примере выше, вы бы использовали
class Package:
def __init__(self):
self.files = []
def __enter__(self):
return self
# ...
def __exit__(self, exc_type, exc_value, traceback):
for file in self.files:
os.unlink(file)
Затем, когда кто-то захочет использовать ваш класс, он сделает следующее:
with Package() as package_obj:
# use package_obj
Переменная package_obj будет экземпляром типа Package (это значение, возвращаемое __enter__
методом). Его __exit__
метод будет вызываться автоматически, независимо от того, происходит ли исключение.
Вы могли бы даже сделать этот подход еще дальше. В приведенном выше примере кто-то еще может создать экземпляр Package, используя его конструктор, не используя with
предложение. Вы не хотите, чтобы это произошло. Вы можете исправить это, создав класс PackageResource , который определяет __enter__
и __exit__
методы. Затем класс Package будет определен строго внутри __enter__
метода и возвращен. Таким образом, вызывающая сторона никогда не сможет создать экземпляр класса Package без использования with
инструкции:
class PackageResource:
def __enter__(self):
class Package:
...
self.package_obj = Package()
return self.package_obj
def __exit__(self, exc_type, exc_value, traceback):
self.package_obj.cleanup()
Вы бы использовали это следующим образом:
with PackageResource() as package_obj:
# use package_obj