The os module

The os module allows to interact with the operating system - find out/change the file structure, environment variables, find out the user name and permissions, etc. A program that uses the variables and functions of the os module is portable from one operating system to another, because os can take into account the characteristics of each OS . However, a number of functions are used only for Windows or Unix-like operating systems.

It should be noted that some of the functionality of the os module is implemented by other Python modules and built-in functions. In this case, it is often better to choose them. For example, the os.access() function checks for file access. If the file is opened for reading or writing, it is easier to use the open() function, and in case of access denial, to handle the PermissionError exception that has occurred.

Below, as an example, some functions of the os module for working with the file system are given.

Get the current directory:

>>> os.getcwd()
'/home/pl/Documents/python'

Change the current directory:

>>> os.chdir('/home')
>>> os.getcwd()
'/home'
>>> os.chdir('./pl/Documents/python')
>>> os.getcwd()
'/home/pl/Documents/python'

Create a directory:

>>> os.mkdir('TEXT')

Create a directory tree:

>>> os.makedirs('ONE/TWO/THREE')
>>> os.listdir('ONE')
['TWO']
>>> os.listdir('ONE/TWO')
['THREE']

The list of directory contents (non-recursive):

>>> os.listdir()
['text4.txt', 'text1.txt', 'text3.txt', 'try_except.py', 'files.py', 'text5.txt', 'grades_oop.py', 'grades.py', 'text6.txt', 'text2.txt', 'text.txt', 'TEXT']
>>> os.listdir('/home')
['pl']

Unlike listdir(), the scandir() function returns an iterator that generates objects of type os.DirEntry that have attributes and methods that you can get information about a file or directory.

>>> list(os.scandir('test'))
[<DirEntry 'Saved'>, <DirEntry 'flag.png'>]
>>> for i in os.scandir('test'):
...     print(i.name, i.path, i.is_dir(), i.is_file())
...     print(i.stat())
...
Saved test/Saved True False
os.stat_result(st_mode=16893, st_ino=4309400, st_dev=66308, st_nlink=2, st_uid=1000, st_gid=1000, st_size=4096, st_atime=1652852331, st_mtime=1652852329, st_ctime=1652852491)
flag.png test/flag.png False True
os.stat_result(st_mode=33279, st_ino=4259361, st_dev=66308, st_nlink=1, st_uid=1000, st_gid=1000, st_size=11039, st_atime=1652852289, st_mtime=1560647773, st_ctime=1652852289)

Both functions (listdir() and scandir()) do not "go" into nested directories. To traverse the directory tree, the os.walk() function is used. About how it works, there is a separate article.

Information about a file or directory:

>>> os.stat('/home')
posix.stat_result(st_mode=16877, st_ino=1048577, st_dev=2053, st_nlink=3, st_uid=0, st_gid=0, st_size=4096, st_atime=1344368518, st_mtime=1339316982, st_ctime=1339316982)
>>> os.stat('text.txt')
posix.stat_result(st_mode=33188, st_ino=1575740, st_dev=2053, st_nlink=1, st_uid=1000, st_gid=1000, st_size=41, st_atime=1344124896, st_mtime=1343895362, st_ctime=1343895362)
>>> s = os.stat('test.c')
>>> s.st_size
67

Rename a file or directory:

>>> os.rename('text2.txt', 'xett.txt')
>>> os.rename('TEXT', 'ETXT')

Deleting a directory:

>>> os.rmdir('ETXT')

You can only delete an empty directory. The same applies to removing a directory tree using the os.removedirs() function. The root directory (which is passed to the function) and all its subdirectories must not contain files.

To remove a file, the os.remove() function is used.

>>> os.mkdir('ABC')
>>> os.replace('test.pas', 'ABC/test.txt')
>>> os.listdir('ABC')
['test.txt']
>>> os.remove('ABC/test.txt')
>>> os.listdir('ABC')
[]

The example above uses the os.replace() function to move and rename a file or directory at the same time.

The os module should be preferred when working with individual files; when working with a group of files, the shutil module is more suitable, which allows to perform operations on data trees.

Copying a directory tree:

>>> shutil.copytree('../python', '../copy-python')
>>> os.listdir('../copy-python')
['text4.txt', 'text1.txt', 'text3.txt', 'try_except.py', 'ONE', 'files.py', 'xett.txt', 'text5.txt', 'grades_oop.py', 'grades.py', 'text6.txt', 'text.txt']

Moving or renaming a tree:

>>> shutil.move('../copy-python', 'python-copy')

Removing a tree:

>>> shutil.rmtree('python-copy')

The os.environ object is like a dictionary and contains a lot of data. It lists environment variables and their values.

>>> os.environ
environ({'SHELL': '/bin/bash', ...
... , '_': '/usr/bin/python3'})

By key, that is, the name of the environment variable, you can get its value:

>>> os.environ['USER']
'pl'
>>> os.environ['PATH']
'/usr/local/sbin:/usr/local/bin ... :/snap/bin'

You can also use the getenv() function to get the values of environment variables:

>>> os.getenv('HOME')
'/home/pl'
>>> os.getenv('_')
'/usr/bin/python3'