Path.open

p.open(...) is open(p, ...). Use it in a with block when you need more than one-shot I/O: appending ('a'), reading line by line, exclusive creation ('x'), or binary streaming.

pathlib methodPython 3.4+
Common call
with p.open('a', encoding='utf-8') as f:
Returns
a file object
Replaces
open(str(p), …)
Watch out
Close it — use with; pass encoding= in text mode
Path.open(modemode — 'r', 'w', 'a', 'x', plus 'b' for binary and '+' for update — as for open().type: str · default: 'r'='r', bufferingbuffering — Buffer policy, as for open().type: int · default: -1=-1, encodingencoding — Text mode only. None = locale encoding.type: str | None · default: None=None, errorserrors — Text mode only: decoding error handler.type: str | None · default: None=None, newlinenewline — Text mode only: newline translation.type: str | None · default: None=None)
→ file object

Parameters

NameTypeRequiredDescription
modestrno ('r')'r', 'w', 'a', 'x', plus 'b' for binary and '+' for update — as for open().
bufferingintno (-1)Buffer policy, as for open().
encodingstr | Noneno (None)Text mode only. None = locale encoding.
errorsstr | Noneno (None)Text mode only: decoding error handler.
newlinestr | Noneno (None)Text mode only: newline translation.

Return value

file object — The same object open() returns (TextIOWrapper, BufferedReader, …).

Common patterns

Append to a log
Mode 'a' creates the file if needed and writes at the end.
from pathlib import Path
with Path('app.log').open('a', encoding='utf-8') as f:
    f.write('started\n')
Stream a large file line by line
Memory stays flat regardless of the file size.
from pathlib import Path
with Path('access.log').open(encoding='utf-8') as f:
    errors = sum(1 for line in f if ' 500 ' in line)
CSV with the csv module
The csv module wants newline='' so it can handle line endings itself.
import csv
from pathlib import Path
with Path('out.csv').open('w', newline='', encoding='utf-8') as f:
    csv.writer(f).writerows(rows)

Examples

1. Write and read with open()
from pathlib import Path p = Path('a.txt') with p.open('w', encoding='utf-8') as f: f.write('one\ntwo\n') with p.open(encoding='utf-8') as f: lines = [line.rstrip('\n') for line in f] lines
Returns
['one', 'two']
2. Append mode
from pathlib import Path p = Path('log.txt') for word in ['a', 'b']: with p.open('a', encoding='utf-8') as f: f.write(word) p.read_text(encoding='utf-8')
Returns
'ab'
3. Exclusive creation
from pathlib import Path p = Path('lock') p.touch() p.open('x')
Returns
FileExistsError: [Errno 17] File exists: 'lock'
4. Binary mode returns bytes
from pathlib import Path p = Path('b.bin') p.write_bytes(bytes([1, 2, 3])) with p.open('rb') as f: head = f.read(2) head
Returns
b'\x01\x02'
5. Same as the built-in open()
from pathlib import Path p = Path('c.txt') p.write_text('x', encoding='utf-8') with p.open(encoding='utf-8') as f1, open(p, encoding='utf-8') as f2: same = type(f1) is type(f2) same
Returns
True

Pitfalls

1. Forgetting to close the file
Data written without closing may still be in the buffer. A with block closes the file even on errors.
read before close
from pathlib import Path
f = Path('x.txt').open('w', encoding='utf-8')
f.write('data')
seen = Path('x.txt').read_text(encoding='utf-8')
f.close()
seen
''
with block
from pathlib import Path
with Path('x.txt').open('w', encoding='utf-8') as f:
    f.write('data')
Path('x.txt').read_text(encoding='utf-8')
'data'
2. Opening a missing file for reading
Mode 'r' requires the file to exist; 'a' and 'w' create it.
'r'
from pathlib import Path
Path('new.txt').open(encoding='utf-8')
FileNotFoundError: [Errno 2] No such file or directory: 'new.txt'
'a'
from pathlib import Path
with Path('new.txt').open('a', encoding='utf-8') as f:
    pass
Path('new.txt').exists()
True

When to use

Use it
  • Appending, streaming, or modes x / r+ / binary
  • Passing a file object to csv, json.dump, pickle …
Reach for something else
  • Whole-file reads and writes → read_text / write_text / read_bytes / write_bytes

Notes

CPython impl
Lib/pathlib/_local.py: io.open(self, mode, buffering, encoding, errors, newline) after io.text_encoding(encoding) in text mode
Built-in
open() accepts a Path directly, so open(p) and p.open() are interchangeable

FAQ

Yes — it calls io.open with the path and the same arguments. Use whichever reads better; open(p) works because paths are os.PathLike.