2013-05-13 3 views
4

У меня есть функция, как:Открыть файл и с заявлением в Python

def func(filename): 
    with open(filename) as f: 
     return [line.split('\t')[0] for line in f] 

ли «с» закрытием файла заявление, даже если есть «внезапное» возвращение функции? Могу ли я игнорировать заявление «с»? то есть безопасно и эквивалентно (с точки зрения утечки памяти),

def func(filename): 
    return [line.split('\t')[0] for line in open(filename)] 

?

ответ

4

Это безопасно. Диспетчер контекста __exit__ вызывается, даже если вы используете return внутри контекста, поэтому дескриптор файла правильно закрыт.

Вот простой тест:

class ContextTest(object): 
    def __enter__(self): 
     print('Enter') 

    def __exit__(self, type, value, traceback): 
     print('Exit') 

def test(): 
    with ContextTest() as foo: 
     print('Inside') 
     return 

Когда вы звоните test(), вы получите:

Enter 
Inside 
Exit 
+0

жаль, что это не так ясно для меня, я могу игнорировать «с» и использовать второй вариант? – elyase

+0

@elyase: В обоих примерах нет утечки памяти, но вы явно не закрываете дескриптор файла во втором, что может привести к проблемам: http://stackoverflow.com/questions/4599980/python-close-file -descriptor-question – Blender

+0

отличный пример! Возможно, вы захотите изменить «... как тест» на что-то еще, он немного затормозил, так как ваше имя функции также проверяется. – monkut

0

Гарантирование это безопасность на самом деле вся цель синтаксиса with...as...; он заменяет блоки try/finally, которые в противном случае были бы довольно неудобными. Так что да, это гарантированно будет безопасным, поэтому я предпочитаю with open as f - f = open.

См. http://effbot.org/zone/python-with-statement.htm для правильного объяснения того, почему существует синтаксис и как он работает. Обратите внимание, что вы можете написать свои собственные классы с помощью методов __enter__ и __exit__, чтобы действительно воспользоваться этим синтаксисом.

Смотрите также ППК для этой функции: http://www.python.org/dev/peps/pep-0343/

Смежные вопросы