Разница между f.close (), f.close и f.closed - PullRequest
0 голосов
/ 03 февраля 2020
with open('new.txt', 'r+') as f:
    print(f.readline())


if f.close:
    print('It is closed')
else:
    print('It is open.')

Если я запускаю этот код, выводит 'It is closed'. Однако если я изменю оператор if с f.close на f.closed(), я получу вывод 'It is open'. Так мой файл закрыт или открыт? Почему я получаю разные результаты?

Ответы [ 2 ]

8 голосов
/ 03 февраля 2020

f.close является ссылкой на метод close объекта file, поэтому всегда читается как True при чтении как логическое значение. f.close() - это вызов этого метода, который ничего не возвращает, поэтому всегда будет иметь значение False, а bool(None) - False. f.closed - это логический атрибут, который сообщает нам, закрыт ли файл. Если вы измените свой код на:

if f.closed:
    print('It is closed')
else:
    print('It is open.')

Это вернет ожидаемый результат. Поскольку вы использовали with ... as f, ваш файл будет автоматически закрыт после того, как вы выйдете из области действия этого оператора, так что вам не придется беспокоиться об использовании f.close().

1 голос
/ 03 февраля 2020

f.close является объектом функции, и поэтому использование if f.close не вызывает функцию. if f.close, таким образом, всегда оценивается как Истина. Кроме того, если метод не существует, он не вернет False, он выдаст синтаксическую ошибку.

>>> type(f.close)
<class 'builtin_function_or_method'>
>>> type(f.doesnotexist)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: '_io.TextIOWrapper' object has no attribute 'doesnotexist'

Вы можете проверить, что if f.close будет вычислять, проверив, что возвращает функция bool(.) :

>>> bool(f.close)
True

Из которого мы можем видеть, что это оценивается как true.

f.closed - это член, который сообщает вам, был ли ваш файл закрыт (что with делает автоматически) , f.close() закрывает ваш файл.

f.closed() вызывает ошибку TypeError, поскольку f.closed является логическим значением и поэтому не может быть вызвано:

>>> f.closed()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'bool' object is not callable
...