Архитектура универсального проекта Django
В ходе последних лет моей разработки проектов Django я понял, что почти все они имеют одно строение.
1. Poetry — создание общей директории
$ poetry new maindir $ tree maindir maindir/ ├── maindir │ └── init.py ├── pyproject.toml ├── README.rst └── tests ├── init.py └── test_maindir.py
«Maindir» в данном случае названа так, чтобы показать, что это исходная директория. В реальной жизни у вас будет название проекта.
2. Установка зависимости Django
$ poetry shell $ poetry add django
3. Создание проекта Django
3.1 Переименовываем внутреннюю директорию maindir to src
$ cd maindir ~/maindir $ mv maindir src $ cd src
3.2 Создаем проект Django внутри папки src
~/maindir/src $ django-admin startproject config .
3.3 Удаляем tests/ и README.rst
$tree maindir maindir/ ├── poetry.lock ├── pyproject.toml └── src ├── config │ ├── asgi.py │ ├── init.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── init.py └── manage.py
4. Инициализация Git
$ git init $ touch .gitignore $ touch README.md
5. Промежуточный итог
maindir/ ├── .git │ ├── . ├── .gitignore ├── poetry.lock ├── pyproject.toml ├── README.md └── src ├── config │ ├── asgi.py │ ├── init.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── init.py └── manage.py
Проект Django находится в директории src.
Остальные файлы и приложения на одном уровне с src/, то есть внутри главной директории всего проекта maindir): например, .gitignore, Dockerfile, deploy/, setup.cfg, poetry.lock и т.д.
6. Открытие проекта в PyCharm
Если вы не используете PyCharm, можете пропустить этот этап, продолжая работать, например, из командной строки без потери функциональности.
6.1 Открываем в PyCharm директорию maindir
6.2 Выбираем виртуальное окружение.
6.2.1 Для этого заходим File/Settings/Project: maindir/Python Interpreter
6.2.2 Жмем «add interpreter», далее «add local interpreter», выбираем Poetry Environment, далее Existing Environment и находим наше окружение по имени или пути, созданное в 1-2 пунктах.
6.3 Указываем PyCharm где нужно применять Django (File/Settings/Languages & Frameworks)

6.4 Помечаем директорию src/ как ресурсную, для этого правой кнопкой мыши кликаем по src, наводим в появившемся окне «Mark Directory as» и выбираем Sources Root.
7. Создание директорий проекта Django
7.1 APPS/
~/maindir/src $ mkdir apps $ touch apps/__init__.py
Или в PyCharm кликаете по src, выбираете New, далее Python Package.
Далее по тексту будем пользоваться именно этим способом.
Абсолютно все приложения django создаются внутри директории apps/.
Чтобы django адекватно подхватывал приложения из apps/, необходимо будет сделать небольшую настройку после создания каждого приложения.
Давайте создадим для примера приложение payment внутри apps/ и настроим:
~/maindir/src $ mkdir apps/payment $ ./manage.py startapp payment apps/payment $ tree ├── apps │ ├── __init__.py │ └── payment │ ├── admin.py │ ├── apps.py │ ├── __init__.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py ├── config .
Отредактируем файл apps/payment/apps.py вот так:

И добавим приложение в config/settings.py
. INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'apps.payment.apps.PaymentConfig' ] .
7.2 API/
Все views.py собираются в этой директории.
Поэтому смело удаляем apps/payment/views.py
Также внутри api/ создаем две директории auth/ и v1/
auth/ — в любом случае, я всегда всегда делаю свою аутентификацию (например, по токену), а также всякие permissions для эндпоинтов API и т.д.
v1/ — версия API, здесь собираются директории (python package, тождественные названию приложений в apps), в которых уже находятся views.py
7.3 UTILS/
В эту директорию запрещается любой импорт из api/ и apps/, и других директорий проекта.
7.4 LIBRARY/
Код для работы с другими API, системами и т.д.
В эту директорию запрещается любой импорт из api/ и apps/, и других директорий проекта, кроме utils/.
7.5 WORKERS/
Задания для Celery
8 Итого: минимальная архитектура проекта Django
├── api │ ├── __init__.py │ └── auth │ │ ├── auth.py │ │ └── permissions.py │ └── v1 │ ├── payment │ │ ├── __init__.py │ │ └── views.py │ ├── __init__.py │ └── urls.py ├── apps │ ├── __init__.py │ └── payment │ ├── admin.py │ ├── apps.py │ ├── __init__.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ └── tests.py ├── config │ ├── asgi.py │ ├── __init__.py │ ├── __pycache__ │ │ ├──. │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── library │ ├── youtube │ │ ├── __init__.py │ │ ├── videos.py │ │ └── . │ ├── __init__.py │ └── . ├── utils │ ├── __init__.py │ ├── numbers.py │ └── . ├── workers │ ├── payment │ │ ├── __init__.py │ │ └── tasks.py │ ├── __init__.py │ └── . ├── __init__.py └── manage.py
P.S.
На самом деле я еще разбиваю config/, а также каждое приложение в директории apps/, но об этом подробнее в другой статье.
Что это за модуль src_rc?
После создания виджета в Qt Designer и переноса в Python с помощью pyuic5 в самом конце кода образовался непонятный импорт: import src_rc .
Вопрос: откуда он взялся и зачем он нужен. Если попробовать его установить pip его не находит.
Вот код:
from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(1246, 698) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) MainWindow.setSizePolicy(sizePolicy) MainWindow.setMinimumSize(QtCore.QSize(1246, 698)) MainWindow.setMaximumSize(QtCore.QSize(1246, 698)) MainWindow.setStyleSheet("background: #191919;") self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.nav_menu = QtWidgets.QGroupBox(self.centralwidget) self.nav_menu.setEnabled(True) self.nav_menu.setGeometry(QtCore.QRect(0, 0, 269, 698)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.nav_menu.sizePolicy().hasHeightForWidth()) self.nav_menu.setSizePolicy(sizePolicy) self.nav_menu.setMinimumSize(QtCore.QSize(269, 0)) self.nav_menu.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.nav_menu.setStyleSheet("border: 0;\n" "background: #151515;") self.nav_menu.setObjectName("nav_menu") self.btn_add_folder = QtWidgets.QLabel(self.nav_menu) self.btn_add_folder.setGeometry(QtCore.QRect(218, 30, 24, 31)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btn_add_folder.sizePolicy().hasHeightForWidth()) self.btn_add_folder.setSizePolicy(sizePolicy) self.btn_add_folder.setMinimumSize(QtCore.QSize(24, 31)) self.btn_add_folder.setMaximumSize(QtCore.QSize(24, 31)) self.btn_add_folder.setText("") self.btn_add_folder.setPixmap(QtGui.QPixmap("F:/Projects/Python/.pyqt/Tasker/src/img/add_folder.svg")) self.btn_add_folder.setObjectName("btn_add_folder") self.logo = QtWidgets.QLabel(self.nav_menu) self.logo.setGeometry(QtCore.QRect(20, 20, 142, 52)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.logo.sizePolicy().hasHeightForWidth()) self.logo.setSizePolicy(sizePolicy) self.logo.setMaximumSize(QtCore.QSize(142, 52)) self.logo.setText("") self.logo.setPixmap(QtGui.QPixmap(":/src/img/logo.svg")) self.logo.setObjectName("logo") self.buttons = QtWidgets.QGroupBox(self.nav_menu) self.buttons.setGeometry(QtCore.QRect(23, 93, 219, 583)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.buttons.sizePolicy().hasHeightForWidth()) self.buttons.setSizePolicy(sizePolicy) self.buttons.setMaximumSize(QtCore.QSize(219, 583)) self.buttons.setTitle("") self.buttons.setObjectName("buttons") self.btn_menu1 = QtWidgets.QPushButton(self.buttons) self.btn_menu1.setGeometry(QtCore.QRect(0, 0, 219, 37)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btn_menu1.sizePolicy().hasHeightForWidth()) self.btn_menu1.setSizePolicy(sizePolicy) self.btn_menu1.setMaximumSize(QtCore.QSize(219, 37)) font = QtGui.QFont() font.setFamily("Inter") font.setPointSize(-1) font.setBold(False) font.setItalic(False) font.setWeight(50) self.btn_menu1.setFont(font) self.btn_menu1.setStyleSheet("background: #1490AA;\n" "border-radius: 11px;\n" "font-family: \'Inter\';\n" "font-style: normal;\n" "font-weight: 400;\n" "font-size: 16px;\n" "line-height: 19px;\n" "text-align: left;\n" "color: #FFFFFF;\n" "padding: 8px 0 8px 15px;") self.btn_menu1.setObjectName("btn_menu1") self.btn_menu2 = QtWidgets.QPushButton(self.buttons) self.btn_menu2.setGeometry(QtCore.QRect(0, 47, 219, 37)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btn_menu2.sizePolicy().hasHeightForWidth()) self.btn_menu2.setSizePolicy(sizePolicy) self.btn_menu2.setMaximumSize(QtCore.QSize(219, 37)) self.btn_menu2.setStyleSheet("background: #282828;\n" "border-radius: 11px;\n" "font-family: \'Inter\';\n" "font-style: normal;\n" "font-weight: 400;\n" "font-size: 16px;\n" "line-height: 19px;\n" "text-align: left;\n" "color: #FFFFFF;\n" "padding: 8px 0 8px 15px;") self.btn_menu2.setObjectName("btn_menu2") self.btn_menu3 = QtWidgets.QPushButton(self.buttons) self.btn_menu3.setGeometry(QtCore.QRect(0, 94, 219, 37)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.btn_menu3.sizePolicy().hasHeightForWidth()) self.btn_menu3.setSizePolicy(sizePolicy) self.btn_menu3.setMaximumSize(QtCore.QSize(219, 37)) self.btn_menu3.setStyleSheet("background: #282828;\n" "border-radius: 11px;\n" "font-family: \'Inter\';\n" "font-style: normal;\n" "font-weight: 400;\n" "font-size: 16px;\n" "line-height: 19px;\n" "text-align: left;\n" "color: #FFFFFF;\n" "padding: 8px 0 8px 15px;") self.btn_menu3.setObjectName("btn_menu3") self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget) self.stackedWidget.setGeometry(QtCore.QRect(269, -20, 977, 719)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.stackedWidget.sizePolicy().hasHeightForWidth()) self.stackedWidget.setSizePolicy(sizePolicy) self.stackedWidget.setMinimumSize(QtCore.QSize(977, 719)) self.stackedWidget.setMaximumSize(QtCore.QSize(977, 719)) self.stackedWidget.setObjectName("stackedWidget") self.page_3 = QtWidgets.QWidget() self.page_3.setObjectName("page_3") self.stackedWidget.addWidget(self.page_3) self.page_4 = QtWidgets.QWidget() self.page_4.setObjectName("page_4") self.stackedWidget.addWidget(self.page_4) MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) self.stackedWidget.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.btn_menu1.setText(_translate("MainWindow", "Все задачи")) self.btn_menu2.setText(_translate("MainWindow", "Папка 1")) self.btn_menu3.setText(_translate("MainWindow", "Папка 2")) import src_rc
Модуль shutil

Модуль shutil содержит набор функций высокого уровня для обработки файлов, групп файлов, и папок. В частности, доступные здесь функции позволяют копировать, перемещать и удалять файлы и папки. Часто используется вместе с модулем os.
Операции над файлами и директориями
shutil.copyfileobj(fsrc, fdst[, length]) — скопировать содержимое одного файлового объекта (fsrc) в другой (fdst). Необязательный параметр length — размер буфера при копировании (чтобы весь, возможно огромный, файл не читался целиком в память).
При этом, если позиция указателя в fsrc не 0 (т.е. до этого было сделано что-то наподобие fsrc.read(47)), то будет копироваться содержимое начиная с текущей позиции, а не с начала файла.
shutil.copyfile(src, dst, follow_symlinks=True) — копирует содержимое (но не метаданные) файла src в файл dst. Возвращает dst (т.е. куда файл был скопирован). src и dst это строки — пути к файлам. dst должен быть полным именем файла.
Если src и dst представляют собой один и тот же файл, исключение shutil.SameFileError.
Если dst существует, то он будет перезаписан.
Если follow_symlinks=False и src является ссылкой на файл, то будет создана новая символическая ссылка вместо копирования файла, на который эта символическая ссылка указывает.
shutil.copymode(src, dst, follow_symlinks=True) — копирует права доступа из src в dst. Содержимое файла, владелец, и группа не меняются.
shutil.copystat(src, dst, follow_symlinks=True) — копирует права доступа, время последнего доступа, последнего изменения, и флаги src в dst. Содержимое файла, владелец, и группа не меняются.
shutil.copy(src, dst, follow_symlinks=True) — копирует содержимое файла src в файл или папку dst. Если dst является директорией, файл будет скопирован с тем же названием, что было в src. Функция возвращает путь к местонахождению нового скопированного файла.
Если follow_symlinks=False, и src это ссылка, dst будет ссылкой.
Если follow_symlinks=True, и src это ссылка, dst будет копией файла, на который ссылается src
copy() копирует содержимое файла, и права доступа.
shutil.copy2(src, dst, follow_symlinks=True) — как copy(), но пытается копировать все метаданные.
shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False) — рекурсивно копирует всё дерево директорий с корнем в src, возвращает директорию назначения.
Директория dst не должна существовать. Она будет создана, вместе с пропущенными родительскими директориями.
Права и времена у директорий копируются copystat(), файлы копируются с помощью функции copy_function (по умолчанию shutil.copy2()).
Если symlinks=True, ссылки в дереве src будут ссылками в dst, и метаданные будут скопированы настолько, насколько это возможно.
Если False (по умолчанию), будут скопированы содержимое и метаданные файлов, на которые указывали ссылки.
Если symlinks=False, если файл, на который указывает ссылка, не существует, будет добавлено исключение в список ошибок, в исключении shutil.Error в конце копирования.
Можно установить флаг ignore_dangling_symlinks=True, чтобы скрыть данную ошибку.
Если ignore не None, то это должна быть функция, принимающая в качестве аргументов имя директории, в которой сейчас copytree(), и список содержимого, возвращаемый os.listdir(). Т.к. copytree() вызывается рекурсивно, ignore вызывается 1 раз для каждой поддиректории. Она должна возвращать список объектов относительно текущего имени директории (т.е. подмножество элементов во втором аргументе). Эти объекты не будут скопированы.
shutil.ignore_patterns(*patterns) — функция, которая создаёт функцию, которая может быть использована в качестве ignore для copytree(), игнорируя файлы и директории, которые соответствуют glob-style шаблонам.
shutil.rmtree(path, ignore_errors=False, onerror=None) — Удаляет текущую директорию и все поддиректории; path должен указывать на директорию, а не на символическую ссылку.
Если ignore_errors=True, то ошибки, возникающие в результате неудавшегося удаления, будут проигнорированы. Если False (по умолчанию), эти ошибки будут передаваться обработчику onerror, или, если его нет, то исключение.
На ОС, которые поддерживают функции на основе файловых дескрипторов, по умолчанию используется версия rmtree(), не уязвимая к атакам на символические ссылки.
На других платформах это не так: при подобранном времени и обстоятельствах «хакер» может, манипулируя ссылками, удалить файлы, которые недоступны ему в других обстоятельствах.
Чтобы проверить, уязвима ли система к подобным атакам, можно использовать атрибут rmtree.avoids_symlink_attacks.
Если задан onerror, это должна быть функция с 3 параметрами: function, path, excinfo.
Первый параметр, function, это функция, которая создала исключение; она зависит от платформы и интерпретатора. Второй параметр, path, это путь, передаваемый функции. Третий параметр, excinfo — это информация об исключении, возвращаемая sys.exc_info(). Исключения, вызванные onerror, не обрабатываются.
shutil.move(src, dst, copy_function=copy2) — рекурсивно перемещает файл или директорию (src) в другое место (dst), и возвращает место назначения.
Если dst — существующая директория, то src перемещается внутрь директории. Если dst существует, но не директория, то оно может быть перезаписано.
shutil.disk_usage(path) — возвращает статистику использования дискового пространства как namedtuple с атрибутами total, used и free, в байтах.
shutil.chown(path, user=None, group=None) — меняет владельца и/или группу у файла или директории.
shutil.which(cmd, mode=os.F_OK | os.X_OK, path=None) — возвращает путь к исполняемому файлу по заданной команде. Если нет соответствия ни с одним файлом, то None. mode это права доступа, требующиеся от файла, по умолчанию ищет только исполняемые.
Архивация
Высокоуровневые функции для созданиия и чтения архивированных и сжатых файлов. Основаны на функциях из модулей zipfile и tarfile.
shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]]) — создаёт архив и возвращает его имя.
base_name это имя файла для создания, включая путь, но не включая расширения (не нужно писать «.zip» и т.д.).
format — формат архива.
root_dir — директория (относительно текущей), которую мы архивируем.
base_dir — директория, в которую будет архивироваться (т.е. все файлы в архиве будут в данной папке).
Если dry_run=True, архив не будет создан, но операции, которые должны были быть выполнены, запишутся в logger.
owner и group используются при создании tar-архива.
shutil.get_archive_formats() — список доступных форматов для архивирования.
shutil.unpack_archive(filename[, extract_dir[, format]]) — распаковывает архив. filename — полный путь к архиву.
extract_dir — то, куда будет извлекаться содержимое (по умолчанию в текущую).
format — формат архива (по умолчанию пытается угадать по расширению файла).
shutil.get_unpack_formats() — список доступных форматов для разархивирования.
Запрос размера терминала вывода
shutil.get_terminal_size(fallback=(columns, lines)) — возвращает размер окна терминала.
fallback вернётся, если не удалось узнать размер терминала (терминал не поддерживает такие запросы, или программа работает без терминала). По умолчанию (80, 24).
Для вставки кода на Python в комментарий заключайте его в теги
- Модуль csv - чтение и запись CSV файлов
- Создаём сайт на Django, используя хорошие практики. Часть 1: создаём проект
- Онлайн-обучение Python: сравнение популярных программ
- Книги о Python
- GUI (графический интерфейс пользователя)
- Курсы Python
- Модули
- Новости мира Python
- NumPy
- Обработка данных
- Основы программирования
- Примеры программ
- Типы данных в Python
- Видео
- Python для Web
- Работа для Python-программистов
- Сделай свой вклад в развитие сайта!
- Самоучитель Python
- Карта сайта
- Отзывы на книги по Python
- Реклама на сайте
Модуль os

Модуль os предоставляет множество функций для работы с операционной системой, причём их поведение, как правило, не зависит от ОС, поэтому программы остаются переносимыми. Здесь будут приведены наиболее часто используемые из них.
Будьте внимательны: некоторые функции из этого модуля поддерживаются не всеми ОС.
os.name - имя операционной системы. Доступные варианты: 'posix', 'nt', 'mac', 'os2', 'ce', 'java'.
os.environ - словарь переменных окружения. Изменяемый (можно добавлять и удалять переменные окружения).
os.getlogin() - имя пользователя, вошедшего в терминал (Unix).
os.getpid() - текущий id процесса.
os.uname() - информация об ОС. возвращает объект с атрибутами: sysname - имя операционной системы, nodename - имя машины в сети (определяется реализацией), release - релиз, version - версия, machine - идентификатор машины.
os.access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True) - проверка доступа к объекту у текущего пользователя. Флаги: os.F_OK - объект существует, os.R_OK - доступен на чтение, os.W_OK - доступен на запись, os.X_OK - доступен на исполнение.
os.chdir(path) - смена текущей директории.
os.chmod(path, mode, *, dir_fd=None, follow_symlinks=True) - смена прав доступа к объекту (mode - восьмеричное число).
os.chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True) - меняет id владельца и группы (Unix).
os.getcwd() - текущая рабочая директория.
os.link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True) - создаёт жёсткую ссылку.
os.listdir(path=".") - список файлов и директорий в папке.
os.mkdir(path, mode=0o777, *, dir_fd=None) - создаёт директорию. OSError, если директория существует.
os.makedirs(path, mode=0o777, exist_ok=False) - создаёт директорию, создавая при этом промежуточные директории.
os.remove(path, *, dir_fd=None) - удаляет путь к файлу.
os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None) - переименовывает файл или директорию из src в dst.
os.renames(old, new) - переименовывает old в new, создавая промежуточные директории.
os.replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None) - переименовывает из src в dst с принудительной заменой.
os.rmdir(path, *, dir_fd=None) - удаляет пустую директорию.
os.removedirs(path) - удаляет директорию, затем пытается удалить родительские директории, и удаляет их рекурсивно, пока они пусты.
os.symlink(source, link_name, target_is_directory=False, *, dir_fd=None) - создаёт символическую ссылку на объект.
os.sync() - записывает все данные на диск (Unix).
os.truncate(path, length) - обрезает файл до длины length.
os.utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True) - модификация времени последнего доступа и изменения файла. Либо times - кортеж (время доступа в секундах, время изменения в секундах), либо ns - кортеж (время доступа в наносекундах, время изменения в наносекундах).
os.walk(top, topdown=True, onerror=None, followlinks=False) - генерация имён файлов в дереве каталогов, сверху вниз (если topdown равен True), либо снизу вверх (если False). Для каждого каталога функция walk возвращает кортеж (путь к каталогу, список каталогов, список файлов).
os.system(command) - исполняет системную команду, возвращает код её завершения (в случае успеха 0).
os.urandom(n) - n случайных байт. Возможно использование этой функции в криптографических целях.
os.path - модуль, реализующий некоторые полезные функции на работы с путями.
Для вставки кода на Python в комментарий заключайте его в теги