Модуль os

Модуль os позволяет взаимодействовать с операционной системой - узнавать/менять файловую структуру, переменные среды, узнавать имя и права пользователя и др. Программа, использующая переменные и функции модуля os, переносима с одной операционной системы на другую, так как os умеет учитывать особенности каждой ОС. Однако ряд функций используется только для Windows или Unix-подобных ОС.

Следует отметить, что часть функциональности os реализуют другие модули и встроенные функции Python. В этом случае нередко лучше выбирать их. Например, функция os.access() проверяет наличие доступа к файлу. Если файл открывается на чтение или запись, проще использовать функцию open(), а в случае запрета на доступ обработать возникшее исключение PermissionError.

Ниже в качестве примера приводятся некоторые функции модуля os для работы с файловой системой.

Узнать текущий каталог:

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

Смена текущего каталога:

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

Создать каталог:

>>> os.mkdir('TEXT')

Создать дерево каталогов:

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

Список содержимого каталога (нерекурсивный):

>>> 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']

В отличие от listdir() функция scandir() возвращает итератор, который генерирует объекты типа os.DirEntry, имеющие атрибуты и методы, с помощью которых можно получить информацию о файле или каталоге.

>>> 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)

Обе функции (listdir() и scandir()) "не заходят" во вложенные каталоги. Для обхода дерева каталогов используется функция os.walk(). О том, как она работает, есть отдельная статья.

Сведения о файле|каталоге:

>>> 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

Переименовать файл|каталог:

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

Удаление каталога:

>>> os.rmdir('ETXT')

Удалить можно только пустую директорию. Это же касается удаления дерева каталогов с помощью функции os.removedirs(). Корневой каталог (который передается в функцию) и все вложенные в него не должны содержать файлов.

Для удаления файла используется функция os.remove().

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

В примере выше используется функция os.replace(), с помощью которой можно переместить и одновременно переименовать файл или каталог.

Модуль os следует предпочесть при работе с индивидуальными файлами, для работы с группой файлов больше подходит модуль shutil, который позволяет выполнять операции над деревьями данных.

Скопировать дерево:

>>> 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']

Перемещение|переименование дерева:

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

Удаление дерева:

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

Объект os.environ похож на словарь, содержит большой объем данных. В нем перечисляются переменные среды и их значения.

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

По ключу, то есть имени переменной среды, можно получить ее значение:

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

Также для получения значений переменных среды можно использовать функцию getenv():

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