Reputation: 726
Python TemporaryDirectory returns string when used in "with" statement
Why does TemporaryDirectory
return a string when used in a with
context?
Here is an example of some Python code which creates a temporary directory tempdir
and prints the corresponding object:
>>> import tempfile
>>> tempdir = tempfile.TemporaryDirectory(dir="/tmp")
>>> print(tempdir)
<TemporaryDirectory '/tmp/tmpf2yh8xu9'>
>>> print(type(tempdir))
<class 'tempfile.TemporaryDirectory'>
As expected, tempdir
is an instance of TemporaryDirectory
.
And here is a similar example, where I use a with
statement when calling TemporaryDirectory
:
>>> import tempfile
>>> with tempfile.TemporaryDirectory(dir="/tmp") as tempdir: print(tempdir)
/tmp/tmp7mlmzegs
>>> with tempfile.TemporaryDirectory(dir="/tmp") as tempdir: print(type(tempdir))
<class 'str'>
In this case, tempdir
is a string. When I look at the __enter__
method of the TemporaryDirectory
class, I see the following:
def __enter__(self):
return self.name
Sure enough - looks like a string is returned instead of the object itself.
What accounts for this discrepancy? Why does the __enter__
method return the file name instead of the file object?
Upvotes: 8
Views: 7301
Reputation: 40056
Why does the enter method return the file name instead of the file object?
There is no discrepancy: tempfile.TemporaryDirectory
is NOT a file object.
It is simply some kind of "context manager" to represent the context within the with
-block, which wraps a str
storing the path created by mkdtemp
. There is nothing meaningful you can work with the TemporaryDirectory
object but getting the name
(for which __enter__
is returning) and cleanup
(for which __exit__
is invoking)
Upvotes: -1
Reputation: 31354
From the source of tempfile.py
, in the TemporaryDirectory
class:
def __enter__(self):
return self.name
As for the "why": The __enter__
and __exit__
methods control the behaviour of the class in a with
block and apparently, the TemporaryDirectory
class chooses to only give you the location - possibly to avoid tampering with the class and the cleanup afterwards. For example, calling .cleanup()
before the end of the with
block.
This would be undesirable:
with TemporaryDirectory('/tmp') as td:
td.cleanup()
And since TemporaryDirectory
offers no other methods beyond that, I think the design decision makes sense, although the surprise for developers is a downside. Code should not be surprising, if it can be avoided.
Upvotes: 6