13

How to create a temporary files/directories with user defined names in python. I am aware of tempfile . However I couldn't see any function with filename as argument.

Note: I need this for unit testing the glob(file name pattern matching) functionality on a temporary directory containing temporary files rather than using the actual file system.

martineau
  • 119,623
  • 25
  • 170
  • 301
hello world
  • 660
  • 2
  • 6
  • 25
  • 3
    Are you aware of the [`tempfile.NamedTemporaryFile()`](https://docs.python.org/2/library/tempfile.html#tempfile.NamedTemporaryFile) function? – martineau Sep 20 '16 at 11:20
  • I think it names the file randomly. Correct me if am wrong – hello world Sep 20 '16 at 11:24
  • 4
    The filename may be be random, but since you can find out what it is (`result.name`), you can rename it just like a normal file. You can also control the directory it is created in via the `dir=` argument. Be sure to use `delete=True` if you don't want it deleted as soon as it's closed. – martineau Sep 20 '16 at 17:09
  • Thanks for the suggestion. This works – hello world Sep 21 '16 at 01:46
  • FYI: `os.rename(r'file path\OLD file name.file type',r'file path\NEW file name.file type')` – Seyhak Ly May 05 '20 at 09:33

3 Answers3

5

If you need to name the temporary files AND directories it looks like you'll have to manage the names and/or creation/deletion yourself.

However, if you just need to control the names of the files you can use tempfile.TemporaryDirectory() to create a temp directory, created your named files in that directory, and then it will all get deleted when it goes out of context.

Like this:

with tempfile.TemporaryDirectory() as temp_dir:
    # open your files here
    named_file = open(os.path.join(temp_dir, "myname.txt"), 'w')

    # do what you want with file...

# directory and files get automatically deleted here...

Additional example:

>>> import tempfile
>>> t = tempfile.TemporaryDirectory()
>>> print(t)
<TemporaryDirectory '/tmp/tmpqign52ry'>
>>> print(t.name)
/tmp/tmpqign52ry
j314erre
  • 2,737
  • 2
  • 19
  • 26
  • 1
    Great answer, thanks. But you don't need `temp_dir.name`, `temp_dir` is all that's required as it's the name of the directory itself. – jigglypuff Apr 25 '22 at 04:01
  • The code actually raises an exception `AttributeError: 'str' object has no attribute 'name'`. Have you tested it? – Jeyekomon Jun 15 '22 at 13:01
  • @Jeyekomon Yes I tested it, see new example above. Behavior might differ with Python version... – j314erre Jun 17 '22 at 15:17
  • 1
    @j314erre I now have used the same Python 3.6.8 and replicated the exception. Please try to actually execute the first example and see the exception. Your second example actually does not verify anything, because while the `TemporaryDirectory()` constructor returns an object, when used as a context manager it returns a plain string. See for yourself or [read the docs](https://docs.python.org/3.6/library/tempfile.html#tempfile.TemporaryDirectory). – Jeyekomon Jun 20 '22 at 08:09
  • @Jeyekomon thanks you are correct, I fixed the code in the answer. – j314erre Jun 26 '22 at 23:23
0

You can use open() with whatever file name you need.

e.g.

open(name, 'w')

Open

Or

import os
import tempfile

print 'Building a file name yourself:'
filename = '/tmp/guess_my_name.%s.txt' % os.getpid()
temp = open(filename, 'w+b')
try:
    print 'temp:', temp
    print 'temp.name:', temp.name
finally:
    temp.close()
    # Clean up the temporary file yourself
    os.remove(filename)

Or you can create a temp directory using mkdtemp and then use open to create a file in the temporary directory.

Techidiot
  • 1,921
  • 1
  • 15
  • 28
0

I almost prefer to write in this convoluted way using NamedTemporaryFile(), instead of using open(), because I really want to emphasize that this is a tempfile:

import tempfile, os

with tempfile.NamedTemporaryFile() as temp_fp:
    os.rename(temp_fp.name, '/tmp/my_custom_name.txt')
    # do stuff here ...

    # do stuff here END ...
    os.rename('/tmp/my_custom_name.txt', temp_fp.name) # finally, rename back
    

We need to rename back because: update file descriptor after os.rename()

Sida Zhou
  • 3,529
  • 2
  • 33
  • 48
  • I'd suggest using a pair of `open` and `os.unlink` over this method. Having to use a "balanced rename" makes this basically the same, except more implicit – Neowizard Aug 18 '22 at 13:01