Утилиты Python

В этом разделе мы рассмотрим некоторые из множества стандартных служебных модулей 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, см. упражнение «Загадка журналов» .