В этом разделе мы рассмотрим некоторые из множества стандартных служебных модулей Python для решения распространенных проблем.
Файловая система -- os, os.path, Shutil
Модули *os* и *os.path* включают множество функций для взаимодействия с файловой системой. Модуль *shutil* может копировать файлы.
- документация по модулю ОС
- filenames = os.listdir(dir) — список имен файлов в этом пути к каталогу (не включая . и ..). Имена файлов — это просто имена в каталоге, а не их абсолютные пути.
- os.path.join(dir, filename) — учитывая имя файла из приведенного выше списка, используйте его, чтобы объединить каталог и имя файла, чтобы создать путь
- os.path.abspath(path) — учитывая путь, возвращает абсолютную форму, например /home/nick/foo/bar.html
- os.path.dirname(path), os.path.basename(path) – заданный dir/foo/bar.html, возвращает имя каталога "dir/foo" и базовое имя "bar.html"
- os.path.exists(path) — true, если он существует
- os.mkdir(dir_path) — создает один каталог, os.makedirs(dir_path) создает все необходимые каталоги по этому пути
- Shutil.copy(source-path, dest-path) — скопируйте файл (каталоги с конечным путем должны существовать)
## Example pulls filenames from a dir, prints their relative and absolute paths def printdir(dir): filenames = os.listdir(dir) for filename in filenames: print(filename) ## foo.txt print(os.path.join(dir, filename)) ## dir/foo.txt (relative to current dir) print(os.path.abspath(os.path.join(dir, filename))) ## /home/nick/dir/foo.txt
Исследование модуля хорошо работает с помощью встроенных функций python help() и dir(). В интерпретаторе выполните «импорт ОС», а затем с помощью этих команд посмотрите, что доступно в модуле: dir(os), help(os.listdir), dir(os.path), help(os.path.dirname ).
Запуск внешних процессов – подпроцесс
Модуль *subprocess* — это простой способ запустить внешнюю команду и записать ее выходные данные.
- документация модуля подпроцесса
- вывод = subprocess.check_output(cmd, stderr=subprocess.STDOUT) — запускает команду, ждет ее завершения и возвращает текст вывода. Команда запускается со стандартным выводом и стандартной ошибкой, объединенными в один выводимый текст. В случае сбоя выдается CalledProcessError.
- Если вам нужен больший контроль над выполнением подпроцесса, см. класс subprocess.popen.
- Существует также простой subprocess.call(cmd), который запускает команду, выгружает ее вывод в ваш вывод и возвращает код ошибки. Это работает, если вы хотите запустить команду, но вам не нужно фиксировать ее вывод в структурах данных Python.
import subprocess ## Given a dir path, run an external 'ls -l' on it -- ## shows how to call an external program def listdir(dir): cmd = 'ls -l ' + dir print("Command to run:", cmd) ## good to debug cmd before actually running it (status, output) = subprocess.getstatusoutput(cmd) if status: ## Error case, print the command's output to stderr and exit sys.stderr.write(output) sys.exit(status) print(output) ## Otherwise do something with the command's output
Исключения
Исключение представляет собой ошибку во время выполнения, которая останавливает нормальное выполнение на определенной строке и передает управление коду обработки ошибок. В этом разделе представлены только самые основные способы использования исключений. Например, ошибка во время выполнения может заключаться в том, что переменная, используемая в программе, не имеет значения (ValueError... вы, вероятно, видели это несколько раз) или ошибка операции открытия файла, поскольку файл не существует ( IOError). Узнайте больше в руководстве по исключениям и просмотрите весь список исключений .
Без какого-либо кода обработки ошибок (как мы делали до сих пор) исключение во время выполнения просто останавливает программу с сообщением об ошибке. Это хорошее поведение по умолчанию, и вы видели его много раз. Вы можете добавить в свой код структуру «try/Exception» для обработки исключений, например:
try: ## Either of these two lines could throw an IOError, say ## if the file does not exist or the read() encounters a low level error. f = open(filename, 'rb') data = f.read() f.close() except IOError: ## Control jumps directly to here if any of the above lines throws IOError. sys.stderr.write('problem reading:' + filename) ## In any case, the code then continues with the line after the try/except
Раздел try: содержит код, который может вызвать исключение. В разделе «исключение:» содержится код, который будет выполняться в случае возникновения исключения. Если исключений нет, раздел исключений: пропускается (то есть этот код предназначен только для обработки ошибок, а не для «нормального» случая кода). Вы можете получить указатель на сам объект исключения с помощью синтаксиса «кроме IOError as e:..» (e указывает на объект исключения).
HTTP – urllib и urlparse
Модуль *urllib.request* обеспечивает получение URL-адреса, делая URL-адрес похожим на файл, из которого можно прочитать. Модуль *urlparse* может разбирать и объединять URL-адреса.
- Документация модуля urllib.request
- ufile = urllib.request.urlopen(url) — возвращает файлоподобный объект для этого URL
- text = ufile.read() -- можно читать из него, как из файла (readlines() и т. д. также работает)
- info = ufile.info() — метаинформация для этого запроса. info.gettype() — это тип mime, например «text/html».
- baseurl = ufile.geturl() — получает «базовый» URL-адрес запроса, который может отличаться от оригинала из-за перенаправлений.
- urllib.request.urlretrieve(url, filename) — загружает данные URL-адреса по указанному пути к файлу.
- urllib.parse.urljoin(baseurl, url) — учитывая URL-адрес, который может быть полным или неполным, и базовый URL-адрес страницы, с которой он получен, возвращается полный URL-адрес. Используйте geturl() выше, чтобы предоставить базовый URL-адрес.
Все исключения находятся в urllib.error.
from urllib.request import urlopen ## Given a url, try to retrieve it. If it's text/html, ## print its base url and its text. def wget(url): ufile = urlopen(url) ## get file-like object for url info = ufile.info() ## meta-info about the url content if info.get_content_type() == 'text/html': print('base url:' + ufile.geturl()) text = ufile.read() ## read all its text print(text)
Приведенный выше код работает нормально, но не включает обработку ошибок, если URL-адрес по какой-либо причине не работает. Вот версия функции, которая добавляет логику try/Exception для вывода сообщения об ошибке в случае сбоя операции URL.
Если urlopen()
зависает, возможно, ваша система не разрешает прямой доступ к некоторым http-адресам. Вы можете убедиться в этом, попытавшись получить тот же URL-адрес с помощью wget
или curl
. Если эти программы также не сработают, вам придется получить http-контент через прокси-службу. Настройка доступа через прокси не рассматривается в этом руководстве.
## Version that uses try/except to print an error message if the ## urlopen() fails. def wget2(url): try: ufile = urlopen(url) if ufile.info().get_content_type() == 'text/html': print(ufile.read()) except IOError: print('problem reading url:', url)
Упражнение
Чтобы попрактиковаться в работе с файловой системой и внешними командами, см. Специальное упражнение по копированию . Чтобы попрактиковаться в использовании материала urllib, см. упражнение «Загадка журналов» .