Skip to content

Commit 337eab7

Browse files
author
Carlos
committed
Update file-directory-path.md to enhance clarity and provide better navigation with links
1 parent f942818 commit 337eab7

File tree

1 file changed

+28
-229
lines changed

1 file changed

+28
-229
lines changed

docs/cheatsheet/file-directory-path.md

Lines changed: 28 additions & 229 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ Handling file and directory Paths
88
</base-title>
99

1010
There are two main modules in Python that deal with path manipulation.
11-
One is the `os.path` module and the other is the `pathlib` module.
11+
One is the <router-link to="/modules/os-module">os.path</router-link> module and the other is the <router-link to="/modules/pathlib-module">pathlib</router-link> module.
1212

1313
<base-disclaimer>
1414
<base-disclaimer-title>
15-
os.path VS pathlib
15+
Pathlib vs Os Module
1616
</base-disclaimer-title>
1717
<base-disclaimer-content>
18-
The `pathlib` module was added in Python 3.4, offering an object-oriented way to handle file system paths.
18+
<code>pathlib</code> provides a lot more functionality than the ones listed above, like getting file name, getting file extension, reading/writing a file without manually opening it, etc. See the <a target="_blank" href="https://docs.python.org/3/library/pathlib.html">official documentation</a> if you intend to know more.
1919
</base-disclaimer-content>
2020
</base-disclaimer>
2121

@@ -26,19 +26,9 @@ folder names. On Unix based operating system such as macOS, Linux, and BSDs,
2626
the forward slash (`/`) is used as the path separator. Joining paths can be
2727
a headache if your code needs to work on different platforms.
2828

29-
Fortunately, Python provides easy ways to handle this. We will showcase
30-
how to deal with both, `os.path.join` and `pathlib.Path.joinpath`
31-
32-
Using `os.path.join` on Windows:
33-
34-
```python
35-
>>> import os
36-
37-
>>> os.path.join('usr', 'bin', 'spam')
38-
# 'usr\\bin\\spam'
39-
```
29+
Fortunately, Python's `pathlib` module provides an easy way to handle this.
4030

41-
And using `pathlib` on \*nix:
31+
Using `pathlib` on \*nix:
4232

4333
```python
4434
>>> from pathlib import Path
@@ -57,25 +47,12 @@ And using `pathlib` on \*nix:
5747
```
5848

5949
Notice the path separator is different between Windows and Unix based operating
60-
system, that's why you want to use one of the above methods instead of
50+
system, that's why you want to use `pathlib` instead of
6151
adding strings together to join paths together.
6252

6353
Joining paths is helpful if you need to create different file paths under
6454
the same directory.
6555

66-
Using `os.path.join` on Windows:
67-
68-
```python
69-
>>> my_files = ['accounts.txt', 'details.csv', 'invite.docx']
70-
71-
>>> for filename in my_files:
72-
... print(os.path.join('C:\\Users\\asweigart', filename))
73-
...
74-
# C:\Users\asweigart\accounts.txt
75-
# C:\Users\asweigart\details.csv
76-
# C:\Users\asweigart\invite.docx
77-
```
78-
7956
Using `pathlib` on \*nix:
8057

8158
```python
@@ -91,42 +68,17 @@ Using `pathlib` on \*nix:
9168

9269
## The current working directory
9370

94-
Using `os` on Windows:
95-
96-
```python
97-
>>> import os
98-
99-
>>> os.getcwd()
100-
# 'C:\\Python34'
101-
>>> os.chdir('C:\\Windows\\System32')
102-
103-
>>> os.getcwd()
104-
# 'C:\\Windows\\System32'
105-
```
106-
107-
Using `pathlib` on \*nix:
71+
You can get the current working directory using `pathlib`:
10872

10973
```python
11074
>>> from pathlib import Path
111-
>>> from os import chdir
11275

11376
>>> print(Path.cwd())
11477
# /home/asweigart
115-
116-
>>> chdir('/usr/lib/python3.6')
117-
>>> print(Path.cwd())
118-
# /usr/lib/python3.6
11978
```
12079

12180
## Creating new folders
12281

123-
Using `os` on Windows:
124-
125-
```python
126-
>>> import os
127-
>>> os.makedirs('C:\\delicious\\walnut\\waffles')
128-
```
129-
13082
Using `pathlib` on \*nix:
13183

13284
```python
@@ -165,20 +117,7 @@ There are also the dot (`.`) and dot-dot (`..`) folders. These are not real fold
165117

166118
### Handling Absolute paths
167119

168-
To see if a path is an absolute path:
169-
170-
Using `os.path` on \*nix:
171-
172-
```python
173-
>>> import os
174-
>>> os.path.isabs('/')
175-
# True
176-
177-
>>> os.path.isabs('..')
178-
# False
179-
```
180-
181-
Using `pathlib` on \*nix:
120+
To see if a path is an absolute path using `pathlib`:
182121

183122
```python
184123
>>> from pathlib import Path
@@ -189,20 +128,7 @@ Using `pathlib` on \*nix:
189128
# False
190129
```
191130

192-
You can extract an absolute path with both `os.path` and `pathlib`
193-
194-
Using `os.path` on \*nix:
195-
196-
```python
197-
>>> import os
198-
>>> os.getcwd()
199-
'/home/asweigart'
200-
201-
>>> os.path.abspath('..')
202-
'/home'
203-
```
204-
205-
Using `pathlib` on \*nix:
131+
You can extract an absolute path with `pathlib`:
206132

207133
```python
208134
from pathlib import Path
@@ -215,17 +141,7 @@ print(Path('..').resolve())
215141

216142
### Handling Relative paths
217143

218-
You can get a relative path from a starting path to another path.
219-
220-
Using `os.path` on \*nix:
221-
222-
```python
223-
>>> import os
224-
>>> os.path.relpath('/etc/passwd', '/')
225-
# 'etc/passwd'
226-
```
227-
228-
Using `pathlib` on \*nix:
144+
You can get a relative path from a starting path to another path using `pathlib`:
229145

230146
```python
231147
>>> from pathlib import Path
@@ -237,24 +153,6 @@ Using `pathlib` on \*nix:
237153

238154
### Checking if a file/directory exists
239155

240-
Using `os.path` on \*nix:
241-
242-
```python
243-
>>> import os
244-
245-
>>> os.path.exists('.')
246-
# True
247-
248-
>>> os.path.exists('setup.py')
249-
# True
250-
251-
>>> os.path.exists('/etc')
252-
# True
253-
254-
>>> os.path.exists('nonexistentfile')
255-
# False
256-
```
257-
258156
Using `pathlib` on \*nix:
259157

260158
```python
@@ -275,21 +173,6 @@ from pathlib import Path
275173

276174
### Checking if a path is a file
277175

278-
Using `os.path` on \*nix:
279-
280-
```python
281-
>>> import os
282-
283-
>>> os.path.isfile('setup.py')
284-
# True
285-
286-
>>> os.path.isfile('/home')
287-
# False
288-
289-
>>> os.path.isfile('nonexistentfile')
290-
# False
291-
```
292-
293176
Using `pathlib` on \*nix:
294177

295178
```python
@@ -307,21 +190,6 @@ Using `pathlib` on \*nix:
307190

308191
### Checking if a path is a directory
309192

310-
Using `os.path` on \*nix:
311-
312-
```python
313-
>>> import os
314-
315-
>>> os.path.isdir('/')
316-
# True
317-
318-
>>> os.path.isdir('setup.py')
319-
# False
320-
321-
>>> os.path.isdir('/spam')
322-
# False
323-
```
324-
325193
Using `pathlib` on \*nix:
326194

327195
```python
@@ -339,15 +207,6 @@ Using `pathlib` on \*nix:
339207

340208
## Getting a file's size in bytes
341209

342-
Using `os.path` on Windows:
343-
344-
```python
345-
>>> import os
346-
347-
>>> os.path.getsize('C:\\Windows\\System32\\calc.exe')
348-
# 776192
349-
```
350-
351210
Using `pathlib` on \*nix:
352211

353212
```python
@@ -365,17 +224,6 @@ Using `pathlib` on \*nix:
365224

366225
## Listing directories
367226

368-
Listing directory contents using `os.listdir` on Windows:
369-
370-
```python
371-
>>> import os
372-
373-
>>> os.listdir('C:\\Windows\\System32')
374-
# ['0409', '12520437.cpx', '12520850.cpx', '5U877.ax', 'aaclient.dll',
375-
# --snip--
376-
# 'xwtpdui.dll', 'xwtpw32.dll', 'zh-CN', 'zh-HK', 'zh-TW', 'zipfldr.dll']
377-
```
378-
379227
Listing directory contents using `pathlib` on \*nix:
380228

381229
```python
@@ -408,19 +256,6 @@ Listing directory contents using `pathlib` on \*nix:
408256
</base-warning-content>
409257
</base-warning>
410258

411-
Using `os.path.getsize()` and `os.listdir()` together on Windows:
412-
413-
```python
414-
>>> import os
415-
>>> total_size = 0
416-
417-
>>> for filename in os.listdir('C:\\Windows\\System32'):
418-
... total_size = total_size + os.path.getsize(os.path.join('C:\\Windows\\System32', filename))
419-
...
420-
>>> print(total_size)
421-
# 1117846456
422-
```
423-
424259
Using `pathlib` on \*nix:
425260

426261
```python
@@ -439,22 +274,20 @@ Using `pathlib` on \*nix:
439274
The `shutil` module provides functions for copying files, as well as entire folders.
440275

441276
```python
442-
>>> import shutil, os
277+
>>> import shutil
443278

444-
>>> os.chdir('C:\\')
445279
>>> shutil.copy('C:\\spam.txt', 'C:\\delicious')
446280
# C:\\delicious\\spam.txt'
447281

448-
>>> shutil.copy('eggs.txt', 'C:\\delicious\\eggs2.txt')
282+
>>> shutil.copy('C:\\eggs.txt', 'C:\\delicious\\eggs2.txt')
449283
# 'C:\\delicious\\eggs2.txt'
450284
```
451285

452286
While `shutil.copy()` will copy a single file, `shutil.copytree()` will copy an entire folder and every folder and file contained in it:
453287

454288
```python
455-
>>> import shutil, os
289+
>>> import shutil
456290

457-
>>> os.chdir('C:\\')
458291
>>> shutil.copytree('C:\\bacon', 'C:\\bacon_backup')
459292
# 'C:\\bacon_backup'
460293
```
@@ -484,60 +317,26 @@ If there is no eggs folder, then `move()` will rename bacon.txt to a file named
484317

485318
## Deleting files and folders
486319

487-
- Calling `os.unlink(path)` or `Path.unlink()` will delete the file at path.
488-
489-
- Calling `os.rmdir(path)` or `Path.rmdir()` will delete the folder at path. This folder must be empty of any files or folders.
490-
320+
- Calling `Path.unlink()` will delete the file at path.
321+
- Calling `Path.rmdir()` will delete the folder at path. This folder must be empty of any files or folders.
491322
- Calling `shutil.rmtree(path)` will remove the folder at path, and all files and folders it contains will also be deleted.
492323

493324
## Walking a Directory Tree
494325

326+
The `Path` object has an `rglob()` method for recursively iterating over files and directories.
327+
495328
```python
496-
>>> import os
329+
>>> from pathlib import Path
497330
>>>
498-
>>> for folder_name, subfolders, filenames in os.walk('C:\\delicious'):
499-
... print(f'The current folder is {folder_name}')
500-
... for subfolder in subfolders:
501-
... print(f'SUBFOLDER OF {folder_name}: {subfolder}')
502-
... for filename in filenames:
503-
... print(f'FILE INSIDE {folder_name}: {filename}')
504-
... print('')
331+
>>> p = Path('C:\\delicious')
332+
>>> for i in p.rglob('*'):
333+
... print(i)
505334
...
506-
# The current folder is C:\delicious
507-
# SUBFOLDER OF C:\delicious: cats
508-
# SUBFOLDER OF C:\delicious: walnut
509-
# FILE INSIDE C:\delicious: spam.txt
510-
511-
# The current folder is C:\delicious\cats
512-
# FILE INSIDE C:\delicious\cats: catnames.txt
513-
# FILE INSIDE C:\delicious\cats: zophie.jpg
514-
515-
# The current folder is C:\delicious\walnut
516-
# SUBFOLDER OF C:\delicious\walnut: waffles
517-
518-
# The current folder is C:\delicious\walnut\waffles
519-
# FILE INSIDE C:\delicious\walnut\waffles: butter.txt
335+
# C:\\delicious\\cats
336+
# C:\\delicious\\walnut
337+
# C:\\delicious\\spam.txt
338+
# C:\\delicious\\cats\\catnames.txt
339+
# C:\\delicious\\cats\\zophie.jpg
340+
# C:\\delicious\\walnut\\waffles
341+
# C:\\delicious\\walnut\\waffles\\butter.txt
520342
```
521-
522-
<base-disclaimer>
523-
<base-disclaimer-title>
524-
Pathlib vs Os Module
525-
</base-disclaimer-title>
526-
<base-disclaimer-content>
527-
`pathlib` provides a lot more functionality than the ones listed above, like getting file name, getting file extension, reading/writing a file without manually opening it, etc. See the <a target="_blank" href="https://docs.python.org/3/library/pathlib.html">official documentation</a> if you intend to know more.
528-
</base-disclaimer-content>
529-
</base-disclaimer>
530-
531-
<see-also>
532-
<see-also-title>
533-
See also
534-
</see-also-title>
535-
<see-also-content>
536-
<ul>
537-
<li><router-link to="/modules/os-module">Python Os Module</router-link></li>
538-
<li><router-link to="/modules/pathlib-module">Python Pathlib Module</router-link></li>
539-
<li><router-link to="/builtin/open">Python open() built-in function</router-link></li>
540-
<li><router-link to="/cheatsheet/reading-and-writing-files">Reading and writing files</router-link></li>
541-
</ul>
542-
</see-also-content>
543-
</see-also>

0 commit comments

Comments
 (0)