The tempfile module creates temporary files and directories that clean up after themselves. Use it instead of manually managing /tmp files.
NamedTemporaryFile
Most common use case—a temp file with a name you can pass around:
import tempfile
# Auto-deleted when closed
with tempfile.NamedTemporaryFile(mode='w', suffix='.txt') as f:
f.write('temporary data')
f.flush()
print(f.name) # /tmp/tmpxyz123.txt
# Pass f.name to other functions
# File deleted hereKeep the file after closing:
with tempfile.NamedTemporaryFile(delete=False) as f:
path = f.name
f.write(b'persistent temp data')
# File still exists at `path`
# You must delete it manually laterTemporaryDirectory
Creates a temp directory that deletes itself:
with tempfile.TemporaryDirectory() as tmpdir:
print(tmpdir) # /tmp/tmpxyz123
# Create files inside
(Path(tmpdir) / 'data.txt').write_text('hello')
# Entire directory deleted hereGreat for test fixtures:
def test_file_processing():
with tempfile.TemporaryDirectory() as tmpdir:
input_file = Path(tmpdir) / 'input.csv'
output_file = Path(tmpdir) / 'output.csv'
input_file.write_text('a,b,c\n1,2,3')
process_csv(input_file, output_file)
assert output_file.exists()SpooledTemporaryFile
Stays in memory until it exceeds a size threshold:
# In memory until > 10KB, then spills to disk
with tempfile.SpooledTemporaryFile(max_size=10240, mode='w+') as f:
f.write('small data stays in RAM')
f.seek(0)
print(f.read())Low-Level Functions
When you need more control:
# Create temp file, get file descriptor and path
fd, path = tempfile.mkstemp(suffix='.log')
try:
os.write(fd, b'log data')
finally:
os.close(fd)
os.unlink(path) # Manual cleanup
# Create temp directory
tmpdir = tempfile.mkdtemp(prefix='myapp_')
try:
# Use tmpdir
pass
finally:
shutil.rmtree(tmpdir) # Manual cleanupPrefer context managers (NamedTemporaryFile, TemporaryDirectory) over these.
Configuration
# Get default temp directory
print(tempfile.gettempdir()) # /tmp on Unix, %TEMP% on Windows
# Create with custom directory
with tempfile.NamedTemporaryFile(dir='/var/cache/myapp') as f:
pass
# Create with prefix
with tempfile.NamedTemporaryFile(prefix='myapp_') as f:
print(f.name) # /tmp/myapp_xyz123Secure Temp Files
tempfile creates files securely:
- Unpredictable names (prevents guessing)
- Restrictive permissions (owner-only on Unix)
- Race-condition safe (atomic creation)
Never do this:
# BAD: predictable name, race condition possible
open(f'/tmp/myapp_{os.getpid()}.txt', 'w')Always use tempfile:
# GOOD: secure, unpredictable
with tempfile.NamedTemporaryFile() as f:
passPractical Example: Safe File Processing
import tempfile
import shutil
from pathlib import Path
def safe_update(filepath: Path, transform_fn):
"""Update a file atomically using temp file."""
content = filepath.read_text()
new_content = transform_fn(content)
# Write to temp file first
with tempfile.NamedTemporaryFile(
mode='w',
dir=filepath.parent, # Same filesystem for atomic move
delete=False
) as tmp:
tmp.write(new_content)
tmp_path = tmp.name
# Atomic replace
shutil.move(tmp_path, filepath)
# Usage
safe_update(
Path('config.json'),
lambda x: x.replace('old_value', 'new_value')
)Quick Reference
| Function | Purpose |
|---|---|
NamedTemporaryFile() | Temp file with accessible path |
TemporaryFile() | Temp file without name (most secure) |
TemporaryDirectory() | Self-cleaning temp directory |
SpooledTemporaryFile() | Memory-first, spills to disk |
mkstemp() | Low-level: returns (fd, path) |
mkdtemp() | Low-level: returns directory path |
gettempdir() | Get system temp directory |
Always prefer context managers for automatic cleanup. Your future self will thank you when there's no temp file debris scattered across /tmp.