# Повторне використання коду та модульність у Python

Автори: Вільям Туркел і Адам Краймбл\
Переклали на українську: Мар’яна Юрків, Анастасія Юрків\
Оригінал уроку: <https://programminghistorian.org/en/lessons/code-reuse-and-modularity>

*Комп’ютерні програми без спеціальних механізмів для керування складністю можуть ставати довгими, громіздкими й заплутаними. У цьому уроці ви побачите, як можна повторно використовувати код, створюючи функції, та ділити програму на модулі, щоб зробити її компактнішою й простішою для налагодження.*

## Цілі уроку

Комп’ютерні програми без спеціальних механізмів для керування складністю можуть ставати довгими, громіздкими й заплутаними. У цьому уроці ви побачите, як можна повторно використовувати код, створюючи *функції*, та ділити програму на *модулі*, щоб зробити її компактнішою й простішою для налагодження. Навіть перенесення лише однієї громіздкої частини програми в окремий модуль значно спрощує роботу з кодом та економить час.

### Функції

Часто виникає потреба повторно використовувати певний набір інструкцій, особливо якщо завдання потрібно виконувати багаторазово. Більшість програм складається з підпрограм, які є достатньо потужними та універсальними для повторного застосування. Такі підпрограми називають функціями, і Python надає інструменти для створення нових функцій. Давайте розглянемо простий приклад функції. Припустимо, ви хочете створити універсальну функцію для привітань. Скопіюйте наведений нижче код у ваш редактор коду, наприклад Visual Studio Code, і збережіть файл під назвою <mark style="color:orange;">`greet.py`</mark>.

```python
# greet.py

def greetEntity(x):
    print("Привіт " + x)

greetEntity("усім")
greetEntity("Цифрові історики")
```

Рядок, що починається з <mark style="color:orange;">`def`</mark>, є визначенням функції. У цьому рядку ми визначаємо (*«def» - define*) функцію, яку назвали «greetEntity». <mark style="color:orange;">`(x)`</mark> — це параметр функції. Незабаром ви зрозумієте, як це працюватиме. Другий рядок містить код функції. Код може складатися з будь-якої кількості рядків, але в цьому прикладі він складається лише з одного.

Зверніть увагу: у Python *відступи* відіграють ключову роль. Порожній простір перед командою <mark style="color:orange;">`print`</mark> вказує інтерпретатору, що цей рядок є частиною функції. Ви дізнаєтеся більше про це згодом, але поки дотримуйтеся відступів за допомогою клавіші Tab, як вказано у прикладі. Запустіть програму, і ви побачите наступний результат:

```python
Привіт усім
Привіт Цифрові історики
```

У цьому прикладі створена одна функція: `greetEntity`. Вона "викликається" (також можна сказати «активується») двічі. Виклик функції означає, що ми вказуємо програмі виконати код, який містить функція. Наприклад, це можна порівняти з тим, як ви кличете свою собаку і за виконану команду нагороджуєте її улюбленим смаколиком. У кожному виклику функції ми передаємо їй потрібний нам параметр. Спробуйте відредагувати файл <mark style="color:orange;">`greet.py`</mark>, щоб викликати функцію `greetEntity` втретє, передавши своє ім’я як параметр. Запустіть програму знову. Тепер ви маєте зрозуміти, що саме робить <mark style="color:orange;">`(x)`</mark> у визначенні функції.

Перш ніж перейти до наступного кроку, відредагуйте файл <mark style="color:orange;">`greet.py`</mark>, видаливши виклики функції, але залишивши саме її визначення. Далі ви навчитеся викликати функцію з іншої програми. Після цього ваш файл <mark style="color:orange;">`greet.py`</mark> повинен виглядати так:

```python
def greetEntity (x):
    print("Привіт " + x)
```

## Модульність

Коли програми невеликі, як у наведеному прикладі, їх зазвичай зберігають у одному файлі. Для виконання такої програми достатньо просто передати файл інтерпретатору. Але якщо програма збільшується і стає громіздкою, буде доцільним розділити її на окремі файли, які називають *модулями*. Такий підхід спрощує роботу з окремими частинами великих програм. Відлагоджуючи кожну частину окремо перед їх об’єднанням, ви не лише полегшуєте повторне використання окремих модулів у інших проєктах, а й спрощуєте виправлення помилок, адже таким чином легше знайти джерело проблеми. Крім того, розбиття програми на модулі дозволяє приховати деталі реалізації певної функціональності в межах відповідного модуля. Інші модулі не повинні знати, як реалізована певна задача, якщо вони за це не відповідають. Такий принцип називається "інкапсуляцією".

Уявіть, що ви створюєте автомобіль. Ви могли б почати додавати деталі навмання, але логічніше спершу побудувати й протестувати окремий модуль — наприклад, двигун — перш ніж переходити до інших компонентів. Двигун, у свою чергу, може складатися з менших модулів, таких як карбюратор чи система запалювання, а ті, своєю чергою, включають ще більш базові елементи. Такий самий підхід застосовується і в програмуванні: спочатку проблема розбивається на дрібніші частини і вирішують їх поступово.

Ви вже створили модуль, коли написали програму <mark style="color:orange;">`greet.py`</mark>. Тепер ви напишите іншу програму, <mark style="color:orange;">`using-greet.py`</mark>, яка імпортує код із вашого модуля та використовує його. У Python є спеціальна команда <mark style="color:orange;">`import`</mark>, що дозволяє одній програмі отримати доступ до вмісту іншого файлу програми. Це саме те, що ми будемо використовувати.

Важливо, що обидва файли — <mark style="color:orange;">`greet.py`</mark> та <mark style="color:orange;">`using-greet.py`</mark> — мають бути збережені в одній і тій самій директорії. Саме тоді Python зможе знайти модуль <mark style="color:orange;">`greet`</mark> та правильно його імпортувати.

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

* додати шлях до директорії з модулем у змінну середовища PYTHONPATH,
* або вказати шлях безпосередньо в коді через модуль sys (наприклад, \ <mark style="color:orange;">`import sys;`</mark>

  <mark style="color:orange;">`sys.path.append`</mark>`("шлях_до_папки")`).

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

Скопіюйте код нижче у ваш редактор і збережіть його як <mark style="color:orange;">`using-greet.py`</mark>. Цей файл буде вашою основною програмою, а <mark style="color:orange;">`greet.py`</mark> — модулем.

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

Скопіюйте код нижче у ваш редактор і збережіть його як <mark style="color:orange;">`using-greet.py`</mark>. Цей файл буде вашою основною програмою, а <mark style="color:orange;">`greet.py`</mark> — модулем.

```python
# using-greet.py

import greet
greet.greetEntity("усім")
greet.greetEntity("Цифрові історики")
```

Тут ми виконали кілька дій. По-перше, ми вказали Python імпортувати (<mark style="color:orange;">`import`</mark>) модуль <mark style="color:orange;">`greet.py`</mark>, який ви створили раніше.

Зверніть увагу, що якщо раніше можна було викликати функцію тільки за її назвою, наприклад, <mark style="color:orange;">`greetEntity("усім")`</mark>, то тепер потрібно додати ім’я модуля, в якому знаходиться функція, та крапку (<mark style="color:orange;">`.`</mark>) перед самою назвою функції. Простими словами, це означає: "*виклич функцію* `greetEntity`, *яку знайдеш у модулі* <mark style="color:orange;">`greet.py`</mark>".

Запустіть вашу програму <mark style="color:orange;">`using-greet.py`</mark>, яку ви створили у вашому редакторі, за допомогою команди "Run Python". Зверніть увагу, що вам не потрібно запускати модуль <mark style="color:orange;">`greet.py`</mark> окремо — достатньо запустити програму, яка його використовує. Якщо все зроблено правильно, у вікні виводу ви побачите таке:

```python
Привіт усім
Привіт Цифрові історики
```

Перш ніж рухатися далі, переконайтеся, що ви розумієте різницю між завантаженням файлу даних (наприклад, <mark style="color:orange;">`helloworld.txt`</mark>) і імпортуванням файлу програми (наприклад, <mark style="color:orange;">`greet.py`</mark>).

## Рекомендовані ресурси

* [W3SchoolsUA - Python: функції ](https://w3schoolsua.github.io/python/python_functions.html#gsc.tab=0)
* [W3SchoolsUA - Python: модулі](https://w3schoolsua.github.io/python/python_modules.html#gsc.tab=0)

### Про авторів

Вільям Туркел, професор історії в Університеті Західного Онтаріо.\
Адам Краймбл, Університетський коледж Лондона.

**Переклад українською:**\
Мар’яна Юрків, доцент кафедри картографії та геопросторового моделювання Національного університету “Львівська політехніка”, [ORCID](https://orcid.org/0000-0002-2180-5583);\
Анастасія Юрків, випускниця Львівського національного університету імені Івана Франка

**Переклад рецензували:**\
Ворожейкін Євген, доцент кафедри інформаційних комунікацій Київського столичного університету імені Бориса Грінченка;\
Віктор Пахолок, студент програми "Комп’ютерні науки" факультету прикладних наук в Українському Католицькому Університеті.

**Рекомендоване цитування:**\
Туркел, Вільям та Краймбл, Адам, "Повторне використання коду та модульність у Python." Programming Historian, переклали Мар’яна Юрків та Анастасія Юрків, *Посібник з цифрової історії*, 2025. DOI: <https://doi.org/10.69915/dh022>
