Теоретичні відомості#

Попередні роботи були пов’язані з об’єктами, що зберігаються в оперативній пам’яті комп’ютера. Тобто після завершення роботи програми всі дії віддалялися. У більшості програм виникає необхідність зберігати інформацію (наприклад, дані про стан) у файлах і завантажувати її з файлів. У мові Python є кілька різних способів виконувати ці дії.

З точки зору програміста, файли бувають двох типів:

  1. Текстові, які містять текст, розбитий на рядки;

  2. Бінарні, в яких можуть міститися будь-які дані; в такиї файлах зберігаються малюнки, звуки, відеофільми. Текстовий файл можна розглядати і як текстовий, і як двійковий, а двійковий як текстовий — не можна.

Структуровані текстові файли#

Для простих текстових файлів єдиним рівнем організації є рядок. Але іноді може знадобитися більш структурований файл. Наприклад, зберегти дані своєї програми для подальшого використання або відправити їх іншій програмі. Існує безліч форматів, які можна розрізнити за такими особливостями:

  • Роздільник, символ на зразок табуляції ('\ t'), коми (',') або вертикальної риски ('|'). Це усе приклади формату зі значеннями, розділеними комою (comma-separated values, CSV).

  • Символи '<' і ‘>', що оточують теги. Приклади включають в себе XML і HTML.

  • Розділові знаки. Прикладом є JavaScript Object Notation (JSON).

  • Виділення пробілами. Прикладом є YAML (що означає YAML Is not Markup Language — «YAML не мова розмітки»).

  • Інші файли, наприклад, конфігураційні.

Кожен з цих форматів структурованих файлів може бути зчитаний і записаний за допомогою як мінімум одного модуля Python. Більш детально із застосуванням цих форматів можна ознайомитися у джерелі [3], стр. 219-228.

У даній лабораторній роботі детально розглядаються текстові файли, елементами яких будуть рядки.

Робота з файлом у програмі мовою Python включає три основних етапи:

  1. Спочатку треба відкрити файл, тобто зробити його доступним для програми. Якщо файл не відкритий, то програма не може до нього звертатися. При відкритті файлу вказують режим роботи з ним.

  2. Коли файл відкритий (доступний), програма виконує всі необхідні операції з ним.

  3. Після виокнання роботи потрібно закрити файл, тобто звільнити його, розірвати його зв’язок із програмою. Саме при закритті всі останні зміни, зроблені програмою у файлі, записуються на диск або інший носій інформації.

Відкриття файлу проводиться за допомогою функції open(). Її формат:

<ім'я файлової змінної> = open(<ім'я файлу>, <режим відкриття >, <encoding = "utf-8"|"ascii"|...>),

де:

<ім'я файлової змінної> — ім’я змінної, за допомогою якої програма буде здійснювати зв’язок з файлом (файловою змінною);

<ім'я файлу> — рядкове представлення імені файлу, що може включати шлях до файлу; більш детально про знаходження абсолютного шляху до файлу з прикладами див. [1], стор.279-282;

<режим відкриття> вказує, чи буде файл інтерпретуватися як текстовий або як двійковий, і для виконання яких дій буде відкритий файл — для читання, для запису, для доповнення в кінець або комбінації цих дій;

<encoding = "utf-8"|"ascii"|...> вказує назву кодування символів у файлі.

Режими можуть містити інформацію про мету відкриття і тип файлу, тобто, наприклад, 'rb' — читання в двійковому режимі, а 'rt' — у текстовому. За замовчуванням використовуэться режим 'rt'. Можливі режими відкриття файлів для функції open() наведені у таблиці 7.1.

Таблиця 7.1. Список режимів доступу до файлу в Python.

r

Відкриває файл тільки для читання. Вказівник стоїть на початку файлу.

rb

Відкриває файл для читання в двійковому форматі. Вказівник стоїть на початку файлу.

r+

Відкриває файл для читання і запису. Вказівник стоїть на початку файлу.

rb+

Відкриває файл для читання і запису в двійковому форматі. Вказівник стоїть на початку файлу.

w

Відкриває файл тільки для запису. Вказівник стоїть на початку файлу. Створює файл, якщо такого не існує.

wb

Відкриває файл для запису в двійковому форматі. Вказівник стоїть на початку файлу. Створює файл, якщо такого не існує.

w+

Відкриває файл для читання і запису. Вказівник стоїть на початку файлу. Створює файл, якщо такого не існує.

wb+

Відкриває файл для читання і запису в двійковому форматі. Вказівник стоїть на початку файлу. Створює файл, якщо такого не існує.

a

Відкриває файл для додавання інформації у файл. Вказівник стоїть в кінці файлу. Створює файл, якщо такого не існує.

ab

Відкриває файл для додавання у двійковому форматі. Вказівник стоїть в кінці файлу. Створює файл, якщо такого не існує.

a+

Відкриває файл для додавання і читання. Вказівник стоїть в кінці файлу. Створює файл, якщо такого не існує.

ab+

Відкриває файл для додавання і читання в двійковому форматі. Вказівник стоїть в кінці файлу. Створює файл, якщо такого не існує.

Приклади#

Відкриття і закриття файлів#

f = open('my_file1.txt')             # Використано режим відкриття за замовчуванням
f2 = open('my_file2.txt', 'w')       # Відкриття файлу на запис
f3 = open('list', 'r')               # Не важливо, як називається файл
fv = open('C:/temp/1.txt')           # Вказано повний шлях до файлу
fv1 = open('/files/1.csv', 'r')      # Вказано відносний шлях до файлу
fv15 = open('../folder/15.csv', 'r') # Вказано відносний шлях до файлу 
file = open('data', 'r+')            # Читання і запис з початку файлу

Warning

Увага! Якщо при відкритті файлу для запису вказати ім’я вже існуючого файлу з інформацією, то вона буде загублена. Якщо файлу не існує - створюється новий. Якщо файл, який відкривається на читання, не знайдений, виникає помилка.

Для закриття файлу призначений метод close(). Приклад:

f.close()
input.close()

Запис інформації в файл#

Для запису інформації в файл використовується метод write(). Наприклад, записати в текстовий файл фразу ‘How beautiful the world is!’ можна так:

# Відкриваємо файл на запис
f = open('some_file', 'w')    # де some_file це ім'я файлу
# Записуємо в нього текст
f.write(' How beautiful the world is! ')
# Якщо більше нічого записуватися не буде - треба закрити файл
f.close()

Ще кілька прикладів програм, в яких відбувається запис інформації в файл.

Приклад 1#

Запис рядка, значення якого задається в ході виконання програми:

f = open('file1', 'w')
s = input('Задайте рядок: ')
f.write(s)
f.close()

Приклад 2#

Запис всіх чисел від 1 до 100 з пробілом між ними:

f = open('file2', 'w')
for n in range(1, 101):
    f.write(f'{n} ')
f.close()

Приклад 3#

Запис всіх символів заданого рядку:

s = input('Задайте рядок: ')
f = open('file3', 'w')
for nom in range(len(s)): # Розглядаємо всі номери символів рядка s
    f.write(s[nom])
f.close()

або

s = input('Задайте рядок: ')
f = open('file3', 'w')
for sim in s:     # Розглядаємо всі символи рядка s
    f.write(sim)
f.close()

Приклад 4#

Запис тексту, який при читанні файлу буде мати вигляд:

Hello,
people!

Програма:

f = open('file4', 'w')
f.write('Hello,\n')
f.write('people!\n')
f.close()

Тут в рядок виведення в файл включено керуючий символ '\ n', символ переходу на наступний рядок. Звернемо увагу на те, що перед цим параметром пробілів немає.

Приклад 5#

Запис кожного символу заданого рядку на окремий рядок файлу:

s = input('Задайте рядок: ')
f = open('file5', 'w')
for sim in s:
    f.write(f'{sim}\n')
f.close()

Приклад 6#

Запис кожного з чисел від 1 до 10 на окремому рядку файлу:

f = open('file6', 'w')
for m in range(1, 11):     # m – числа, які записуються 
    f.write(f'{m}\n')
f.close()

Приклад 7#

Запис кожного елементу заданого списку зі значень строкового типу на окремому рядку файлу:

sp = [1, 2, 3] #Заданий список
f = open('file7', 'w')
for i in range(len(sp)):
    f.write(sp[i] + '\n')
f.close()

У Python є можливість записати в файл всі елементи списку за допомогою методу writelines():

sp = [1, 2, 3]
f = open('file7', 'w')
f.writelines(sp)
f.close()

Приклад 8#

Запис кожного з 10 заданих назв футбольних клубів на окремому рядку файлу:

f = open('file8', 'w')
for k in range(10):
    # Введення чергової назви
    club = input('Введіть назву клубу: ')
    # Запис його в файл
    f.write(club + '\n')
f.close()

Файли, створені в результаті виконання цих програм, знадобляться для прикладів, розглянутих далі.

Читання інформації з файлу#

Для читання рядка текстового файлу використовується метод readline() . Наприклад, програма для виведення на екран першого рядка файлу, пов’язаного з файловою змінною f, має вигляд:

f = open('file1', 'r')
# Читаємо 1-й рядок файлу і запам'ятовуємо його в змінній s
s = f.readline()
f.close()
# Друкуємо значення змінної s
print(s)

Якщо розробити таку програму для виведення на екран двох рядків файлу, створеного у прикладі 4 вище:

# Відкриваємо файл для читання
f = open('file4', 'r')
# Читаємо 1-й рядок файлу і запам'ятовуємо його в змінній s
s = f.readline()
# Друкуємо значення змінної s
print(s)
# Те ж саме з 2-м рядком
s = f.readline()
print(s)
# Закриваємо файл
f.close()

і виконати її, то результат буде (як і вимагалося в умові прикладу) таким:

Hello,

people!

Чому між двома рядками, прочитаними з файлу, виводиться порожній рядок? Справа в тому, що під час запису тексту в файл в кінець кожного рядка був записаний керуючий символ '\n', символу переходу на наступний рядок. Тому після виведення першого рядка ('Hello,') відбувся перехід на наступний рядок екрана. А згідно з правилами роботи інструкції print(), після її виконання також відбувається перехід на наступний рядок. Тому, щоб виключити виведення порожнього рядка, слід або включити в інструкцію print() параметр end = '', при якому переходу на наступний рядок після виведення не буде:

f = open('file4', 'r')
s = f.readline()
# друкуємо змінну s
print(s, end='')
s = f.readline()
print(s, end='')
f.close()

або не виводити керуючий символ (це можна зробити, використовуючи зріз рядка):

f = open('file4', 'r')
s = f.readline()
# Друкуємо змінну s, використовуючи зріз
print(s[:-1])
s = f.readline()
print(s[:-1])
f.close()

Керуючий символ \n можна також виключити з прочитаного рядка s за допомогою методу rstrip(). Цей метод видаляє кінцеві символи рядка (за замовчуванням — пробільні символи).

Розв’яжемо ще ряд завдань, в яких відбувається читання інформації з файлу.

Завдання 1#

Вивести на екран всі рядки файлу, створеного при вирішенні прикладу 5. Порожніх рядків між ними бути не повинно.

n = 1 # n – число рядків у файлі
f = open('file5', 'r')
for k in range(n):
    s = f.readline()
    print(s, end='')
f.close()

Але в цьому випадку, якщо зазначене n більше кількості рядків у файлі, то в кінець при виведенні додаються порожні рядки. Довжину файлу можна визначити так:

len(open('file').readlines())`

або інакше:

import  re
len(re.findall(r"[\n]+", open('file').read())) # виведе кількість без порожніх рядків

Завдання 2#

Вивести на екран всі рядки файлу, створеного при вирішенні прикладу 6. Порожніх рядків між ними бути не повинно.

f = open('file6', 'r')
for k in range(10):
    s = f.readline()
    print(s[:-1])
f.close()

Завдання 3#

Для файлу, створеного при вирішенні прикладу 7, вивести на екран рядок з заданим номером n. Список не використовувати.

Текстовий файл називають “файлом послідовного доступу до даних”. Це означає, що для того, щоб прочитати 100-е за рахунком значення з файлу, потрібно спочатку прочитати попередні 99. У своїй внутрішній пам’яті система зберігає положення вказівника (файлового курсора), який визначає поточне місце в файлі. При відкритті файлу вказівник встановлюється в самий початок файлу, при читанні зміщується на позицію, наступну за прочитаними даними. Якщо потрібно повторити читання з початку файлу, потрібно його закрити, а потім знову відкрити. Тому для вирішення завдання треба прочитати, але не використовувати перші (n - 1) рядків файлу, а потім прочитати і вивести на екран n-й рядок.

n = int(input('Задайте номер рядку файла: '))
f = open('file7', 'r')
# Пропускаємо перші (n - 1) рядків 
for k in range(n - 1):
    s = f.readline()
# Читаємо рядок з номером n і запам'ятовуємо його в змінній s
s = f.readline()
#Виводимо його
print(s) # Керуючий символ в кінці рядка можна не виключати
f.close()

Завдання 4#

Всі рядки файлу, створеного при розв’язанні прикладу 7, записати у список.

sp = [] # заповнюваний список
f = open('file7', 'r')
n = 10 # n – число рядків у файлі
for k in range(n):
    s = f.readline()  # Читаємо черговий рядок файлу і запам'ятовуємо його в змінній s
    sp.append(s[:-1]) # Додаємо значення s без керуючого символу в якості нового# элемента списка
f.close()

В Python є оригінальні можливості записати всі рядки текстового файлу в список. Зокрема, це можна зробити за допомогою методу readlines() або генераторного виразу і методу strip(). Наприклад, для отримання списку а, що складається з усіх рядків файла, зв’язаного в програмі з файловою змінною f, необхідно записати:

a = f.readlines()

або

а = [line.strip() for line in f]

Ще один оригінальний спосіб — одночасне використання методів read() і split():

a = f.read().split()

Перший метод читає всі рядки файлу і представляє їх як один рядок, а другий — поділяє його на вихідні частини за символом \n і записує їх окремо в список.

Можна також записати в список всі слова одного рядка текстового файлу. Для цього треба:

# Прочитати цей рядок:
s = f.readline()
# Отримати список його слів:
slova = s.split()

Наявність або відсутність керуючого символу в кінці кожного елемента списку у всіх перерахованих варіантах встановіть самостійно.

У всіх розглянутих задачах кількість рядків текстового файлу, що читається, було відомо (2, n і 10). А якщо це не так? У подібних випадках для читання всіх рядків можна використовувати інструкцію циклу for зі змінною line, відповідної кожному рядку файлу:

f = open('file', 'r')
for line in f: # Для всіх рядків файлу 
    s = line   # значення рядків
    # ...

Наприклад, програма для виведення на екран всіх рядків файлу без порожніх рядків між ними має вигляд:

f = open('file7', 'r')
for line in f:
    print(line, end='')
f.close()

Завдання 5#

Всі рядки файлу, створеного при розв’язанні прикладу 5, записати в інший файл. Список не використовувати.

f = open('file5', 'r')        # Відкриваємо існуючий файл на читання,
file = open('new_file5', 'w') # а новий файл - на запис

for line in f:       # Для всіх рядків вихідного файлу:
    file.write(line) # Значення чергового рядка записуємо в інший файл,
                     # в тому числі і керуючий символ \n
f.close()
file.close()

Завдання 6#

Використовуючи файл, створений при розв’язанні прикладу 5, визначити номер рядку, в якій записано деякий символ sym. Прийняти, що такий символ у файлі зустрічається рівно один раз. Список не використовувати.

Це завдання може бути вирішена різними засобами. Можна розглянути всі рядки файлу, визначаючи при цьому номер кожного рядка. Якщо значення в рядку (без врахування останнього, керуючого символу) збігається з відшукуваним символом, то номер цього рядка потрібно запам’ятати:

sym = input('Задайте символ: ')
f = open('file5', 'r')

line_number  = 0 # Поточний номер рядка файлу (умовне початкове значення)
found_number = 0 # шуканий номер рядка

for line in f:       # Для кожного рядка файлу:
    line_number += 1 # визначаємо його номер

    # Порівнюємо значення в рядку без керуючого символу
    # з шуканим символом (використовуємо зріз)
    if line[:-1] == sym: # Зустрівся шуканий символ
        # Запам'ятовуємо номер поточного рядка файлу
        found_number = line_number

# виводимо відповідь
print(f'Цей символ знаходиться в рядку номер: {found_number}')
f.close()

Однак це спосіб нераціональний при великому числі рядків у файлі (шуканий символ може виявитися вже на початку файлу, а ми читаємо і перевіряємо всі його рядки). Можна проводити перевірку рядків тільки до знаходження шуканого символу. Це можна зробити двома способами:

  • Використовувати інструкції for і break:

sym = input('Задайте символ: ')
f = open('file5', 'r')

line_number  = 0 # Поточний номер рядка файлу (умовне початкове значення)
found_number = 0 # шуканий номер рядка

for line in f:       # Для кожного рядка файлу:
    line_number += 1 # визначаємо його номер

    # Порівнюємо значення в рядку без керуючого символу
    # з шуканим символом (використовуємо зріз)
    if line[:-1] == sym: # Зустрівся шуканий символ
        # Запам'ятовуємо номер поточного рядка файлу
        found_number = line_number
        break

# виводимо відповідь
print(f'Цей символ знаходиться в рядку номер: {found_number}')
f.close()
  • Використовувати інструкцію while:

sym = input ('Задайте символ: ')
f = open ('file5', 'r')

line_num = 1      # Номер рядка файлу
s = f.readline () # Його значення (символ)

while s[:-1] != sym: # Поки не зустрінеться шуканий символ
    # Переходимо до наступного рядка (читаємо його)
    s = f.readline()
    # Номер цього рядка
    line_number += 1

# Зупинилися на рядку з заданим символом
print (f'Цей символ знаходиться в рядку номер {line_number}')
f.close()

Зверніть увагу на необхідність виключення зі значення прочитаного рядка керуючого символу. Це необхідно робити завжди, коли рядок файлу порівнюється зі “звичайним” рядком.

Завдання 7#

Використовуючи файл, створений при вирішенні прикладу 5, визначити, чи є в файлі заданий символ sym. Список не використовувати.

Для вирішення можна використовувати змінну exst_sym логічного типу, що визначає, чи є в файлі заданий символ (якщо є, то ця змінна має значення True, інакше — False).

sym = input ('Задайте символ: ')
f = open ('file5', 'r')

# Спочатку символ не знайденo
exst_sym = False
for line in f: # Для кожного рядка файлу:
    # Порівнюємо його із заданим символом
    if line[:-1] == sym: # Якщо зустрівся шуканий символ
        exst_sym = True  # Міняємо значення прапорця
        break            # Припиняємо цикл

# Виводимо відповідь
if exst_sym: 
    print('Даний символ у файлі є')
else:
    print ('Даного символу у файлі немає')
f.close()

Можна також використовувати інструкцію while:

sym = input ('Задайте символ: ')
f = open ('file5', 'r')

exst_sym = False
while not exst_sym:  # Доки не зустрінеться шуканий символ:
    s = f.readline() # Читаємо черговий рядок файлу
    # Порівнюємо його із заданим символом
    if s[:-1] == sym:   # Зустрівся шуканий символ
        exst_sym = True # Міняємо значення прапорця

# ...

Завдання 8#

У текстовому файлі countries.txt на окремих рядках записані назви 10 держав, у файлі capitals.txt — їх столиці (також на окремих рядках і в тому ж порядку, що і назви держав).

Дано назву держави. Визначити її столицю. Списки не використовувати.

Вирішення цього завдання являє собою “суму” рішень завдань 6 і 3:

country = input('Введіть назву держави: ')

# Визначаємо номер рядка у файлі country.txt,
# В якому записано назву заданої держави
f1 = open('country.txt', 'r')
line_number  = 0
found_number = 0

for line in f1: # Для кожного рядка файлу
    line_number += 1 # визначаємо його номер
    # Порівнюємо значення в рядку з шуканою назвою
    if line[:-1] == country:       # Якщо зустрілася шукана назва
        found_number = line_number # Запам'ятовуємо номер поточного рядка файлу
        break # Припиняємо роботу циклу

# Закриваємо файл gosud.txt
f1.close ()

# Шукаємо рядок з номером found_number у файлі capitals.txt
f2 = open('capitals.txt', 'r')
for k in range(found_number - 1):
    s = f2.readline() # Пропускаємо перші (found_number - 1) рядків

# Читаємо рядок з номером found_number
s = f2.readline()
# Виводимо його значення
print(f'Столиця цієї держави: {s}')
# Закриваємо файл capitals.txt
f2.close()

Можна також не читати перші “непотрібні” рядки, а ведучи підрахунок рядків, знайти рядок із номером found_number і вивести його на екран:

# Шукаємо рядок з номером found_number в файлі capitals.txt
f2 = open('capitals.txt', 'r')
line_number = 0
for line in f2:      # Для кожного рядка файлу
    line_number += 1 # визначаємо його номер
    if line_number == found_number: # Зустрівся рядок з потрібним номером
        print ('Столиця цієї держави:', line) # Виводимо його значення
        break # Припиняємо роботу циклу
# Закриваємо файл capitals.txt
f2.close()

Для читання всіх рядків файлу можна використовувати також такий дуже короткий варіант:

for s in open(file_name):
    # ...

У ньому в змінній s будуть перебиратися значення всіх рядків. Звернемо увагу на те, що:

  1. Відкривати файл для читання окремої інструкцією не потрібно.

  2. У інструкції open() можна не вказувати режиму відкриття файлу для читання.

  3. Закривати файл за допомогою методу close() не потрібно, він закриється автоматично після закінчення циклу for.

Іноді, читаючи рядки файлу по одному, необхідно визначити, коли дані закінчилися. У таких випадках логіка дій повинна бути такою:

while not кінець файлу:
    читаємо черговий рядок
    використовуємо зчитаний рядок
    if кінець файлу:
        break

Для того щоб визначити, коли файл закінчився, можна використовувати особливість методу readline(): коли файловий курсор вказує на кінець файлу, цей метод повертає порожній рядок, який сприймається як помилкове логічне значення (False).

Це дозволяє застосувати аналог циклу з постумовою:

while True:
    s = f.readline()
    if not s:
        break
    print(s, end='')

або передумовою:

s = f.readline()
while s:
    print(s, end='')
    s = f.readline()

У цьому прикладі при отриманні порожнього рядка цикл читання і виведення на екран рядків файлу закінчується за допомогою інструкції break. Аналогічно можна знайти кількість рядків у файлі:

f = open('file', 'r')
k = 0
s = f.readline()
while s:
    k += 1
    s = f.readline()
f.close()
print(k)

Кількість рядків у файлі можна визначити також, використовуючи інструкцію циклу for.

Зміна файлів#

Запис в файл нового рядка#

Для вирішення завдання треба відкрити файл на додавання до нього інформації, після чого записати в нього новий рядок і закрити файл:

f = open('file', 'a')
f.write(new_str + '\n')
f.close()

Звернемо увагу на необхідність використання під час запису керуючого символу \n.

Заміна рядка файлу#

Припустимо, потрібно в існуючому файлі замінити рядок із заданим номером k на деякий новий рядок new_str. На перший погляд, здається, що можна вчинити так:

# відкрити файл на читання і запис
f = open('file', 'r+')
# прочитати, але не використовувати перші (k - 1) рядків файлу
for i in range(k - 1):
    s = f.readline()
# записати в поточний рядок файлу нове значення
f.write(new_str + '\n')

Однак при цьому потрібний результат отриманий не буде (переконайтеся у цьому). Правильне рішення:

# відкрити файл на читання
f = open('file', 'r')
# всі рядки файлу записати в список
sp = f.readlines()
# закрити файл
f.close()

# змінити відповідне значення в списку
sp[k - 1] = new_str + '\ n'

# записати всі елементи нового списку в той же файл
f = open('file', 'w')
for el in sp:
    f.write(el)
f.close()

З використанням списку вирішуються також завдання:

  • видалення рядка файлу; вставки у файл нового рядка;

  • обміну місцями двох рядків файлу;

  • перестановки всіх рядків файлу в зворотньому порядку;

  • сортування рядків файлу.

Використання оператора with#

В Python є акуратно вбудований інструмент, який може помітно спростити читання і редагування файлів, званий менеджером контексту. Оператор with створює диспетчер контексту в Python, який автоматично закриває файл, по закінченню роботи з ним.

Як це працює:

with open("test.txt") as file_handler:
    for line in file_handler:
        print(line)

Можна виконувати всі стандартні операції введення/виводу в межах блоку коду, у звичному порядку. Після виходу з блоку коду, файловий дескриптор закриє його, і його вже не можна буде використовувати. Оператор закриває файл автоматично.

Як дізнатися позицію вказівника у файлі в Python#

Після того як викликаний метод read() на файловому об’єкті, якщо повторно викликати read(), то буде порожній рядок. Це відбувається тому, що після першого прочитання вказівник знаходиться в кінці файлу. Для того щоб дізнатися позицію вказівника можна використовувати метод tell().

Приклад:

my_file = open("some.txt")
my_file.read(10) # ми хочемо прочитати 10 символів
print("Я на позиції:", my_file.tell())
my_file.close()

Говорячи простіше, метод tell() повідомляє у скількох байтах чи символах (в залежності від типу файлу) від початку файлу ми зараз знаходимося. Щоб перейти на потрібну позицію, слід використовувати інший метод — seek().

Синтаксис методу seek():

my_file.seek(offset, [from])

Метод seek() змінює поточну позицію у файлі. Аргумент offset вказує на скільки байт перейти. Опціональний аргумент from означає позицію, з якої починається рух. 0 означає початок файлу, 1 — нинішня позиція, 2 — кінець файлу.

Приклад:

my_file = open("some.txt", "r")
print(my_file.read (10))
print("Ми знаходимося на позиції:", my_file.tell())

# Повертаємося в початок
my_file.seek(0)
print(my_file.read(10))
my_file.close()

Модуль OS і робота з файловою системою#

Ряд можливостей по роботі з каталогами та файлами надає вбудований модуль os. Хоча він містить багато функцій, розглянемо лише основні з них:

  • mkdir(): створює нову папку

  • rmdir(): видаляє папку

  • rename(): перейменовує файл

  • remove(): видаляє файл

Створення та видалення папки#

Для створення папки застосовується функція mkdir(), в яку передається шлях до створюваної папки:

import os

os.mkdir ("hello") # Шлях щодо поточного скрипта

# Абсолютний шлях
os.mkdir ("c: // somedir")
os.mkdir ("c: // somedir / hello")

Для видалення папки використовується функція rmdir(), в яку передається шлях до видаленої папки:

import os

# Шлях відносно поточного скрипта
os.rmdir("hello")

# абсолютний шлях
os.rmdir("c://somedir/hello")

Перейменування файлу#

Для перейменування викликається функція rename(source, target), перший параметр якої — шлях до вихідного файлу, а другий — нове ім’я файлу. В якості шляхів можуть використовуватися як абсолютні, так і відносні. Наприклад, нехай в папці C:/SomeDir/ розташовується файл somefile.txt. Перейменуємо його у файл hello.txt:

import os

os.rename("C://SomeDir//somefile.txt", "C://SomeDir//hello.txt")

Видалення файлу#

Для видалення викликається функція remove(), в яку передається шлях до файлу:

import os

os.remove("C://SomeDir//hello.txt")

Існування файлу#

Якщо спробувати відкрити файл, який не існує, то Python видасть виняток FileNotFoundError. Для відлову виключення можна використовувати конструкцію try ... except. Однак можна вже до відкриття файлу перевірити, чи існує він чи ні за допомогою методу os.path.exists(path). У цей метод передається шлях, який необхідно перевірити:

filename = input("Введіть шлях до файлу: ")
if os.path.exists(filename):
    print("Зазначений файл існує")
else:
    print("Файл не існує")

Додаткові важливі функції роботи з os#

Кожна програма має поточний каталог. Функція os.getcwd повертає поточний каталог:

import os

cwd = os.getcwd()
print(cwd)

Перевірити наявність файлу в поточному каталозі:

os.path.exists('my_file')

Наступний приклад рекурсивно виводить список всіх файлів і підкаталогів для даного каталогу:

import os

def walk(dir):
    for name in os.listdir(dir):
        path = os.path.join(dir, name)
    if os.path.isfile(path):
        print(path)
    else:
        walk(path)

walk(path)

У наступному прикладі виводиться статистична інформація щодо поточного каталогу: загальний розмір каталогу в байтах, число файлів, число підкаталогів. Стандартна функція os.path.walk має три параметри: каталог, користувацька функція, список для підрахунку:

import os, sys

def getlocaldata(sms, dr, flst):
    for f in flst:
        fullf = os.path.join(dr, f)
        if os.path.islink(fullf): continue # don't count linked files
        if os.path.isfile(fullf):
            sms[0] += os.path.getsize(fullf)
            sms[1] += 1
        else:
            sms[2] += 1

def dtstat(dtroot):
    sums = [0, 0, 1] # 0 bytes, 0 files, 1 directory so far
    os.path.walk(dtroot, getlocaldata, sums)
    return sums

report = dtstat('.')
print(report)

У наступному прикладі зроблена інтерпретація системної утиліти grep. У поточному каталозі будуть знайдені файли з пітоновськім розширенням, в яких буде знайдений пошуковий рядок 'import os':

import os, sys, fnmatch.

mask = '*.py'
pattern = 'import os'

def walk(arg, dir, files):
    for file in files:
        if fnmatch.fnmatch(file,mask):
            name = os.path.join(dir,file)
            try:
                data = open(name,'rb').read()
                if data.find(pattern) != -1:
                    print(name)
            except: 
                pass

os.path.walk('.', walk, [])