Reputation: 99
with open('new.txt', 'r+') as f:
print(f.readline())
if f.close:
print('It is closed')
else:
print('It is open.')
If I run this code, outputs 'It is closed'
. However, if I change the if statement from f.close
to f.closed()
, I get the output 'It is open'
. So is my file closed or open? Why am I getting different outputs?
Upvotes: 0
Views: 10397
Reputation: 14506
f.close
is a reference to the close
method of the file
object, so always evaluates as True
when read as a boolean. f.close()
is a call to that method, which does not return anything, so will always evaluate to False
, as bool(None)
evaluates to False
. f.closed
is a boolean attribute which tells us whether or not the file is closed. If you alter your code to:
if f.closed:
print('It is closed')
else:
print('It is open.')
This will return the result you expect. As you have used with ... as f
, your file will be closed automatically after you leave the scope of that statement, so you don't have to worry about using f.close()
anyway.
Upvotes: 11
Reputation: 678
f.close
is the function object, and as such using if f.close
does not call the function.
if f.close
thus always evaluates as True. Further, if the method did not exist, it would not return False, it would provide a syntax error.
>>> 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'
You can check what if f.close
will evaluate to by checking what the bool(.)
function returns:
>>> bool(f.close)
True
From which we can see that this evaluates to true.
f.closed
is the member that tells you whether your file has been closed (which with
does automatically), f.close()
closes your file.
f.closed()
raises a TypeError, because f.closed
is a boolean and thus can not be called:
>>> f.closed()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'bool' object is not callable
Upvotes: 1