ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 05.12.2023
Просмотров: 857
Скачиваний: 3
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
308
Часть I. Основы языка Python
copy2(<Копируемый файл>, <Куда копируем>)
— позволяет скопировать файл вместе с метаданными. Если файл существует, он будет перезаписан. Если файл не удалось скопировать, возбуждается исключение
OSError или одно из исключений, являющихся подклассом этого класса. В качестве результата возвращает путь скопированного файла:
>>> shutil.copy2(r"file.txt", r"file4.txt")
1 ... 26 27 28 29 30 31 32 33 ... 83
move(<Путь к файлу>, <Куда перемещаем>)
— перемещает файл в указанное место с уда- лением исходного файла. Если файл существует, он будет перезаписан. Если файл не удалось переместить, возбуждается исключение
OSError или одно из исключений, являющихся подклассом этого класса. В качестве результата возвращает путь переме- щенного файла.
Пример перемещения файла file4.txt в каталог
C:\book\test
:
>>> shutil.move(r"file4.txt", r"C:\book\test")
Для переименования и удаления файлов предназначены следующие функции из модуля os
:
rename(<Старое имя>, <Новое имя>)
— переименовывает файл. Если файл не удалось переименовать, возбуждается исключение
OSError или одно из исключений, являющих- ся подклассом этого класса.
Пример переименования файла с обработкой исключений: import os # Подключаем модуль try: os.rename(r"file3.txt", "file4.txt") except OSError: print("Файл не удалось переименовать") else: print("Файл успешно переименован")
remove(<Путь к файлу>)
и unlink(<Путь к файлу>)
— позволяют удалить файл. Если файл не удалось удалить, возбуждается исключение
OSError или одно из исключений, являющихся подклассом этого класса:
>>> os.remove(r"file2.txt")
>>> os.unlink(r"file4.txt")
Модуль os.path содержит дополнительные функции, позволяющие проверить наличие файла, получить размер файла и др. Опишем эти функции:
exists(<Путь или дескриптор>)
— проверяет указанный путь на существование. В ка- честве параметра можно передать путь к файлу или целочисленный дескриптор откры- того файла, возвращенный функцией open()
из того же модуля os
. Возвращает
True
, если путь существует, и
False
— в противном случае:
>>> import os.path
>>> os.path.exists(r"file.txt"), os.path.exists(r"file2.txt")
(True, False)
>>> os.path.exists(r"C:\book"), os.path.exists(r"C:\book2")
(True, False)
getsize(<Путь к файлу>)
— возвращает размер файла в байтах. Если файл не существу- ет, возбуждается исключение
OSError
:
>>> os.path.getsize(r"file.txt") # Файл существует
18
Глава 16. Работа с файлами и каталогами
309
>>> os.path.getsize(r"file2.txt") # Файл не существует
... Фрагмент опущен ...
OSError: [Error 2] Не удается найти указанный файл: 'file2.txt'
getatime(<Путь к файлу>)
— возвращает время последнего доступа к файлу в виде ко- личества секунд, прошедших с начала эпохи. Если файл не существует, возбуждается исключение
OSError
:
>>> import time # Подключаем модуль time
>>> t = os.path.getatime(r"file.txt")
>>> t
1511773416.0529847
>>> time.strftime("%d.%m.%Y %H:%M:%S", time.localtime(t))
'27.11.2017 12:03:36'
getctime(<Путь к файлу>)
— возвращает дату создания файла в виде количества секунд, прошедших с начала эпохи. Если файл не существует, возбуждается исключение
OSError
:
>>> t = os.path.getctime(r"file.txt")
>>> t
1511773416.0529847
>>> time.strftime("%d.%m.%Y %H:%M:%S", time.localtime(t))
'27.11.2017 12:03:36'
getmtime(<Путь к файлу>)
— возвращает время последнего изменения файла в виде ко- личества секунд, прошедших с начала эпохи. Если файл не существует, возбуждается исключение
OSError
:
>>> t = os.path.getmtime(r"file.txt")
>>> t
1511773609.980973
>>> time.strftime("%d.%m.%Y %H:%M:%S", time.localtime(t))
'27.11.2017 12:06:49'
Получить размер файла и время создания, изменения и доступа к файлу, а также значения других метаданных, позволяет функция stat()
из модуля os
. В качестве значения функция возвращает объект stat_result
, содержащий десять атрибутов: st_mode
, st_ino
, st_dev
, st_nlink
, st_uid
, st_gid
, st_size
, st_atime
, st_mtime и st_ctime
Пример использования функции stat()
:
>>> import os, time
>>> s = os.stat(r"file.txt")
>>> s os.stat_result(st_mode=33206, st_ino=5910974511035376, st_dev=2086732993, st_nlink=1, st_uid=0, st_gid=0, st_size=15, st_atime=1511773416, st_mtime=1511773609, st_ctime=1511773416)
>>> s.st_size # Размер файла
15
>>> t = s.st_atime # Время последнего доступа к файлу
>>> time.strftime("%d.%m.%Y %H:%M:%S", time.localtime(t))
'27.11.2017 12:03:36'
>>> t = s.st_ctime # Время создания файла
>>> time.strftime("%d.%m.%Y %H:%M:%S", time.localtime(t))
'27.11.2017 12:03:36'
310
Часть I. Основы языка Python
>>> t = s.st_mtime # Время последнего изменения файла
>>> time.strftime("%d.%m.%Y %H:%M:%S", time.localtime(t))
'27.11.2017 12:06:49'
Обновить время последнего доступа и время изменения файла позволяет функция utime()
из модуля os
. Функция имеет два варианта формата: utime(<Путь к файлу или его дескриптор>, None) utime(<Путь к файлу или его дескриптор >, (<Последний доступ>, <Изменение файла>))
В качестве первого параметра можно указать как строковый путь, так и целочисленный дескриптор открытого файла, возвращенный функцией open()
из модуля os
. Если в качестве второго параметра указано значение
None
, то время доступа и изменения файла будет теку- щим. Во втором варианте формата функции utime()
указывается кортеж из новых значений в виде количества секунд, прошедших с начала эпохи. Если файл не существует, возбужда- ется исключение
OSError
Пример использования функции utime()
:
>>> import os, time
>>> os.stat(r"file.txt") # Первоначальные значения os.stat_result(st_mode=33206, st_ino=5910974511035376, st_dev=2086732993, st_nlink=1, st_uid=0, st_gid=0, st_size=15, st_atime=1511773416, st_mtime=1511773609, st_ctime=1511773416)
>>> t = time.time() - 600
>>> os.utime(r"file.txt", (t, t)) # Текущее время минус 600 сек
>>> os.stat(r"file.txt") os.stat_result(st_mode=33206, st_ino=5910974511035376, st_dev=2086732993, st_nlink=1, st_uid=0, st_gid=0, st_size=15, st_atime=1511790710, st_mtime=1511790710, st_ctime=1511773416)
>>> os.utime(r"file.txt", None) # Текущее время
>>> os.stat(r"file.txt") os.stat_result(st_mode=33206, st_ino=5910974511035376, st_dev=2086732993, st_nlink=1, st_uid=0, st_gid=0, st_size=15, st_atime=1511791343, st_mtime=1511791343, st_ctime=1511773416)
16.7. Преобразование пути к файлу или каталогу
Преобразовать путь к файлу или каталогу позволяют следующие функции из модуля os.path
:
abspath(<Относительный путь>)
— преобразует относительный путь в абсолютный, учи- тывая местоположение текущего рабочего каталога:
>>> import os.path
>>> os.path.abspath(r"file.txt")
'C:\\book\\file.txt'
>>> os.path.abspath(r"folder1/file.txt")
'C:\\book\\folder1\\file.txt'
>>> os.path.abspath(r"../file.txt")
'C:\\file.txt'
Как уже отмечалось ранее, в относительном пути можно указать как прямые, так и об- ратные слэши. Все они будут автоматически преобразованы с учетом значения атрибута
Глава 16. Работа с файлами и каталогами
311 sep из модуля os.path
. Значение этого атрибута зависит от используемой операционной системы. Выведем значение атрибута sep в операционной системе Windows:
>>> os.path.sep
'\\'
При указании пути в Windows следует учитывать, что слэш является специальным сим- волом. По этой причине слэш необходимо удваивать (экранировать) или вместо обыч- ных строк использовать неформатированные строки:
>>> "C:\\temp\\new\\file.txt" # Правильно 'C:\\temp\\new\\file.txt'
>>> r"C:\temp\new\file.txt" # Правильно 'C:\\temp\\new\\file.txt'
>>> "C:\temp\new\file.txt" # Неправильно!!!
'C:\temp\new\x0cile.txt'
Кроме того, если слэш расположен в конце строки, то его необходимо удваивать даже при использовании неформатированных строк:
>>> r"C:\temp\new\" # Неправильно!!!
SyntaxError: EOL while scanning string literal
>>> r"C:\temp\new\\"
'C:\\temp\\new\\\\'
В первом случае последний слэш экранирует закрывающую кавычку, что приводит к синтаксической ошибке. Решить эту проблему можно, удвоив последний слэш. Однако посмотрите на результат — два слэша превратились в четыре. От одной проблемы ушли, а к другой пришли. Поэтому в данном случае лучше использовать обычные строки:
>>> "C:\\temp\\new\\" # Правильно 'C:\\temp\\new\\'
>>> r"C:\temp\new\\"[:-1] # Можно и удалить слэш 'C:\\temp\\new\\'
isabs(<Путь>)
— возвращает
True
, если путь является абсолютным, и
False
— в против- ном случае:
>>> os.path.isabs(r"C:\book\file.txt")
True
>>> os.path.isabs("file.txt")
False
basename(<Путь>)
— возвращает имя файла без пути к нему:
>>> os.path.basename(r"C:\book\folder1\file.txt")
'file.txt'
>>> os.path.basename(r"C:\book\folder")
'folder'
>>> os.path.basename("C:\\book\\folder\\")
''
dirname(<Путь>)
— возвращает путь к папке, где хранится файл:
>>> os.path.dirname(r"C:\book\folder\file.txt")
'C:\\book\\folder'
>>> os.path.dirname(r"C:\book\folder")
'C:\\book'
312
Часть I. Основы языка Python
>>> os.path.dirname("C:\\book\\folder\\")
'C:\\book\\folder'
split(<Путь>)
— возвращает кортеж из двух элементов: пути к папке, где хранится файл, и имени файла:
>>> os.path.split(r"C:\book\folder\file.txt")
('C:\\book\\folder', 'file.txt')
>>> os.path.split(r"C:\book\folder")
('C:\\book', 'folder')
>>> os.path.split("C:\\book\\folder\\")
('C:\\book\\folder', '')
splitdrive(<Путь>)
— разделяет путь на имя диска и остальную часть пути. В качестве значения возвращается кортеж из двух элементов:
>>> os.path.splitdrive(r"C:\book\folder\file.txt")
('C:', '\\book\\folder\\file.txt')
splitext(<Путь>)
— возвращает кортеж из двух элементов: пути с именем файла, но без расширения, и расширения файла (фрагмент после последней точки):
>>> os.path.splitext(r"C:\book\folder\file.tar.gz")
('C:\\book\\folder\\file.tar', '.gz')
join(<Путь1>[, ..., <ПутьN>])
— соединяет указанные элементы пути, при необходи- мости вставляя между ними разделители:
>>> os.path.join("C:\\", "book\\folder", "file.txt")
'C:\\book\\folder\\file.txt'
>>> os.path.join(r"C:\\", "book/folder/", "file.txt")
'C:\\\\book/folder/file.txt'
Обратите внимание на последний пример — в пути используются разные слэши, и в ре- зультате получен некорректный путь. Чтобы этот путь сделать корректным, необходимо воспользоваться функцией normpath()
из того же модуля os.path
:
>>> p = os.path.join(r"C:\\", "book/folder/", "file.txt")
>>> os.path.normpath(p)
'C:\\book\\folder\\file.txt'
16.8. Перенаправление ввода/вывода
При рассмотрении методов для работы с файлами говорилось, что значение, возвращаемое методом fileno()
, всегда будет больше числа 2, т. к. число 0 закреплено за стандартным вводом stdin
, 1 — за стандартным выводом stdout
, а 2 — за стандартным выводом сооб- щений об ошибках stderr
. Все эти потоки имеют некоторое сходство с файловыми объек- тами. Например, потоки stdout и stderr поддерживают метод write()
, предназначенный для вывода сообщений, а поток stdin
— метод readline()
, служащий для получения вво- димых пользователем данных. Если этим потокам присвоить ссылку на объект, поддержи- вающий файловые методы, то можно перенаправить стандартные потоки в соответствую- щий файл. Для примера так и сделаем:
>>> import sys # Подключаем модуль sys
>>> tmp_out = sys.stdout # Сохраняем ссылку на sys.stdout
Глава 16. Работа с файлами и каталогами
313
>>> f = open(r"file.txt", "a") # Открываем файл на дозапись
>>> sys.stdout = f # Перенаправляем вывод в файл
>>> print("Пишем строку в файл")
>>> sys.stdout = tmp_out # Восстанавливаем стандартный вывод
>>> print("Пишем строку в стандартный вывод")
Пишем строку в стандартный вывод
>>> f.close() # Закрываем файл
В этом примере мы вначале сохранили ссылку на стандартный вывод в переменной tmp_out
С помощью этой переменной можно в дальнейшем восстановить вывод в стандартный поток.
Функция print()
напрямую поддерживает перенаправление вывода. Для этого использует- ся параметр file
, который по умолчанию ссылается на стандартный поток вывода. Напри- мер, записать строку в файл можно так:
>>> f = open(r"file.txt", "a")
>>> print("Пишем строку в файл", file=f)
>>> f.close()
Параметр flush позволяет указать, когда следует выполнять непосредственное сохранение данных из промежуточного буфера в файле. Если его значение равно
False
(это, кстати, значение по умолчанию), сохранение будет выполнено лишь после закрытия файла или по- сле вызова метода flush()
. Чтобы указать интерпретатору Python выполнять сохранение после каждого вызова функции print()
, следует присвоить этому параметру значение
True
:
>>> f = open(r"file.txt", "a")
>>> print("Пишем строку в файл", file = f, flush = True)
>>> print("Пишем другую строку в файл", file = f, flush = True)
>>> f.close()
Стандартный ввод stdin также можно перенаправить. В этом случае функция input()
будет читать одну строку из файла при каждом вызове. При достижении конца файла возбуждает- ся исключение
EOFError
. Для примера выведем содержимое файла с помощью перенаправ- ления потока ввода (листинг 16.4).
Листинг 16.4. Перенаправление потока ввода
# -*- coding: utf-8 -*- import sys tmp_in = sys.stdin # Сохраняем ссылку на sys.stdin f = open(r"file.txt", "r") # Открываем файл на чтение sys.stdin = f # Перенаправляем ввод while True: try: line = input() # Считываем строку из файла print(line) # Выводим строку except EOFError: # Если достигнут конец файла, break # выходим из цикла sys.stdin = tmp_in # Восстанавливаем стандартный ввод f.close() # Закрываем файл input()
314
Часть I. Основы языка Python
Если необходимо узнать, ссылается ли стандартный ввод на терминал или нет, можно вос- пользоваться методом isatty()
. Метод возвращает
True
, если объект ссылается на терми- нал, и
False
— в противном случае:
>>> tmp_in = sys.stdin # Сохраняем ссылку на sys.stdin
>>> f = open(r"file.txt", "r")
>>> sys.stdin = f # Перенаправляем ввод
>>> sys.stdin.isatty() # Не ссылается на терминал
False
>>> sys.stdin = tmp_in # Восстанавливаем стандартный ввод
>>> sys.stdin.isatty() # Ссылается на терминал
True
>>> f.close() # Закрываем файл
Перенаправить стандартный ввод/вывод можно также с помощью командной строки. Для примера создадим в папке
C:\book файл test3.py с кодом, приведенным в листинге 16.5.
Листинг 16.5. Содержимое файла test3.py
# -*- coding: utf-8 -*- while True: try: line = input() print(line) except EOFError: break
Запускаем командную строку и переходим в папку со скриптом, выполнив команду: cd
C:\book
. Теперь выведем содержимое созданного ранее текстового файла file.txt
(его содер- жимое может быть любым), выполнив команду:
C:\Python36\python.exe test3.py < file.txt
Перенаправить стандартный вывод в файл можно аналогичным образом. Только в этом случае символ
<
необходимо заменить символом
>
. Для примера создадим в папке
C:\book файл test4.py с кодом из листинга 16.6.
Листинг 16.6. Содержимое файла test4.py
# -*- coding: utf-8 -*- print("String") # Эта строка будет записана в файл
Теперь перенаправим вывод в файл file.txt
, выполнив команду:
C:\Python36\python.exe test4.py > file.txt
В этом режиме файл file.txt будет перезаписан. Если необходимо добавить результат в конец файла, следует использовать символы
>>
. Вот пример дозаписи в файл:
C:\Python36\python.exe test4.py >> file.txt
С помощью стандартного вывода stdout можно создать индикатор выполнения процесса непосредственно в окне консоли. Чтобы реализовать такой индикатор, нужно вспомнить, что
Глава 16. Работа с файлами и каталогами
315 символ перевода строки в Windows состоит из двух символов:
\r
(перевод каретки) и
\n
(перевод строки). Таким образом, используя только символ перевода каретки
\r
, можно перемещаться в начало строки и перезаписывать ранее выведенную информацию. Рассмот- рим вывод индикатора процесса на примере (листинг 16.7).
Листинг 16.7. Индикатор выполнения процесса
# -*- coding: utf-8 -*- import sys, time for i in range(5, 101, 5): sys.stdout.write("\r ... %s%%" % i) # Обновляем индикатор sys.stdout.flush() # Сбрасываем содержимое буфера time.sleep(1) # Засыпаем на 1 секунду sys.stdout.write("\rПроцесс завершен\n") input()
Сохраним код в файл и запустим его с помощью двойного щелчка. В окне консоли записи будут заменять друг друга на одной строке каждую секунду. Так как данные перед выводом будут помещаться в буфер, мы сбрасываем их на диск явным образом с помощью метода flush()
16.9. Сохранение объектов в файл
Сохранить объекты в файл и в дальнейшем восстановить объекты из файла позволяют модули pickle и shelve
. Модуль pickle предоставляет следующие функции:
dump(<Объект>, <Файл>[, <Протокол>][, fix_imports=True])
— производит сериализа- цию объекта и записывает данные в указанный файл. В параметре
<Файл>
указывается файловый объект, открытый на запись в бинарном режиме.
Пример сохранения объекта в файл:
>>> import pickle
>>> f = open(r"file.txt", "wb")
>>> obj = ["Строка", (2, 3)]
>>> pickle.dump(obj, f)
>>> f.close()
load()
— читает данные из файла и преобразует их в объект. Формат функции: load(<Файл>[, fix_imports=True][, encoding="ASCII"]
[, errors="strict"])
В параметре
<Файл>
указывается файловый объект, открытый на чтение в бинарном ре- жиме.
Пример восстановления объекта из файла:
>>> f = open(r"file.txt", "rb")
>>> obj = pickle.load(f)
>>> obj
['Строка', (2, 3)]
>>> f.close()