Русский
Русский
English
Статистика
Реклама

Перевод Самая лучшая практика работа с path в Python


Все та же проблема: список папок и дисков

В последней статье мы использовали рекурсивную функцию размером менее 10 строк для решения проблемы сканирования папок и ранжирования файлов по дате изменения и размеру.

Теперь я подниму планку и покажу, как можно было сделать лучше.

Объединяем пути с помощью Pathlib

Старые идеи в новом обличье?

Предыдущее решение с соединением путей выглядело следующим образом:

path_file = os.sep.join([path_dir, filename])

Преимущество такого подхода заключается в том, что решение не зависит от операционной системы, и вам не нужно складывать строки с помощью оператора + или форматирования.

Тем не менее, здесь можно допустить ошибку, например, непреднамеренно или ошибочно определить путь к каталогу с помощью закрывающего разделителя.

path_dir: str = r"C:/Users/sselt/Documents/blog_demo/"  # abschlieender Trennerfilename: str = "some_file"path_file = os.sep.join([path_dir, filename])# C:/Users/sselt/Documents/blog_demo/\some_file

Несмотря на то, что в этом примере показан рабочий код, неправильный разделитель приведет к ошибке при вызове этого пути. И такие ошибки могут возникать всякий раз, когда далекие от кода пользователи оперируют путями в конфигурационных файлах, не обращая внимания на соглашения.

В Python 3.4 появилось лучшее решение модуль pathlib. Он обрабатывает функции файлов и папок модуля os с помощью объектно-ориентированного подхода.

Напомню, старый вариант выглядел вот так:

import ospath = "C:/Users/sselt/Documents/blog_demo/"os.path.isdir(path)os.path.isfile(path)os.path.getsize(path)

А вот альтернативный:

from pathlib import Pathpath: Path = Path("C:/Users/sselt/Documents/blog_demo/")path.is_dir()path.is_file()path.stat().st_size

Оба варианта дают один и тот же результат. Так чем же второй вариант лучше?

Объектно-ориентированный и более устойчивый к ошибкам

Вызовы в основном являются объектно-ориентированными, нравится вам это или нет, но лично мне такой подход по душе. Здесь у нас есть такой объект, как определение path, у которого есть атрибуты и методы.

Однако пример с операторами перегрузки в данном случае более интересен:

filename: Path = Path("some_file.txt")path: Path = Path("C:/Users/sselt/Documents/blog_demo")print( path / filename )# C:\Users\sselt\Documents\blog_demo\some_file.txt

Сначала разделение на два пути кажется недопустимым. Однако объект path был перегружен так, чтобы работать как объединенный путь.

В дополнение к этому синтаксическому сахару объекты path будут перехватывать другие типичные ошибки:

filename: Path = Path("some_file.txt")# hier path mit berflssigem Trenner am Schlusspath: Path = Path("C:/Users/sselt/Documents/blog_demo/")# hier path mit doppeltem Trennerpath: Path = Path("C:/Users/sselt/Documents/blog_demo//")# hier path vllig durcheinanderpath: Path = Path("C:\\Users/sselt\\Documents/blog_demo")  # hier ein wilder Mix# alle Varianten fhren zum selben Ergebnisprint(path/filename)# C:\Users\sselt\Documents\blog_demo\some_file.txt

Такой вариант не только приятнее, но и устойчивее к неправильным входным данным. В дополнение к другим преимуществам код также не привязан к определенной операционной системе. Он определяет только generic объект path, который объявляется в системе Windows как WindowsPath, а в Linux как PosixPath.

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

Обработка пути с помощью os.walk

В своей последней статье я использовал os.listdir, os.path.isdir и рекурсивную функцию для итерации по дереву путей и разграничения файлов и папок.

Но os.walk предлагает решение получше. Этот метод создает не список, а итератор, который можно вызывать построчно. В результате мы получим соответствующий путь к папке и список всех файлов по этому пути. Весь процесс происходит рекурсивно, поэтому вы получите все файлы одним вызовом.

Лучшее решение с os.walk и Pathlib

Если вы объедините два вышеупомянутых метода, то получите решение, которое будет более простым, полностью независимым от операционной системы, устойчивым к неправильным форматам путей и без явных рекурсий:

filesurvey = []for row in os.walk(path):   # row beinhaltet jeweils einen Ordnerinhalt    for filename in row[2]:  # row[2] ist ein tupel aus Dateinamen        full_path: Path = Path(row[0]) / Path(filename)   # row[0] ist der Ordnerpfad        filesurvey.append([path, filename, full_path.stat().st_mtime, full_path.stat().st_size])

Если вам удастся улучшить этот вариант, не постесняйтесь рассказать мне об этом. Я был бы рад вашим отзывам!

Первую часть статьи можно найти здесь.


Перевод статьи подготовлен в преддверии старта курса Python Developer. Basic.

Также приглашаем всех желающих принять участие в бесплатном демо-уроке курса на тему Три кита: map(), filter() и zip().

Можно ли писать код, требующий циклов, но без циклов? Может ли он быть быстрее, чем, если бы мы использовали циклы в Python? Для реализации задуманного понадобится знание слов "callback", "iterator" и "lambda". Если интересно присоединяйтесь!

Источник: habr.com
К списку статей
Опубликовано: 02.02.2021 02:11:38
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании otus. онлайн-образование

Python

Программирование

Lambda

Iterator

Path

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru