Вхід у світ DevOps-37 Python04

Це четверта історія та продовження нашої попередньої розповіді з серії про Python. У цій історії ми розглянемо наступні теми:

  • Простір імен
  • Скрипти
  • Модулі
  • Пакети

pic

Бібліотека -> Пакети -> Підпакети -> Модулі

Простір імен

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

В Python є кілька рівнів просторів імен:

  1. Глобальний простір імен: Це найвищий рівень простору імен для програми, що включає всі змінні та функції, визначені на глобальному рівні.
  2. Простір імен модуля: Кожен модуль має власний простір імен. Змінні, функції та класи, визначені в модулі, є частиною простору імен цього модуля.
  3. Простір імен функції: Коли ви визначаєте змінні або функції всередині функції, ці імена існують у власному локальному просторі імен функції.
  4. Вбудований простір імен: Python має вбудований простір імен для функцій та виключень (як-от print(), len(), Exception тощо).
% cat func_arg.py   
x = 100 # Глобальна змінна  

def my_function():  
 x = 10 # Локальна змінна  
 y = 20 # Локальна змінна  
 print(f"Локальний x всередині функції: {x}")  
 print(dir())  

my_function()  
print(f"Глобальний x поза функцією: {x}")  

print(dir())  

% python func_arg.py  
Локальний x всередині функції: 10  
['x', 'y']  
Глобальний x поза функцією: 100  
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'my_function', 'x']  



- Змінна x всередині my_function є локальною і існує тільки  
в межах області видимості функції (локальний простір імен).  

- x, визначена поза функцією, є глобальною змінною та є частиною  
глобального простору імен.  

- Коли викликається my_function(), друкується локальна змінна x (значення 10),  
але глобальна x (значення 100) залишається незмінною.

Функція dir() в Python використовується для повернення списку дійсних атрибутів (імен) для об'єкта. Вона може бути використана для перевірки атрибутів та методів об'єкта, модуля, класу чи вбудованого простору імен - dir([object]).

  • Якщо передано аргумент object, dir() повертає список атрибутів цього об'єкта.
  • Якщо аргумент не передано, функція повертає список імен в поточній області видимості (локальній або глобальній).

Python Скрипти

Python скрипт — це по суті Python програма, яка виконується безпосередньо інтерпретатором Python. Зазвичай це самостійні програми, які використовуються для автоматизації завдань або виконання специфічних операцій. __name__ — це спеціальна вбудована змінна в Python, яка вказує на ім'я модуля.

Характеристики Python скриптів:
Виконуваність: Скрипт зазвичай виконується безпосередньо через команду python, наприклад, python script.py.
Точка входу: В Python точка входу скрипту зазвичай визначається через конструкцію if __name__ == “__main__”:. Умова if __name__ == "__main__": дає значення True, і викликається функція main().
Якщо скрипт імпортується як модуль, name встановлюється на ім'я скрипта (наприклад, script).

% cat func_arg.py   
def greet(name):  
 print(f"Hello, {name}!")  
 print(f"Друкуємо ім'я модуля з функції greet: {__name__}")  

def main():  
 # Основна логіка програми  
 user_name = input("Введіть ваше ім'я: ")  
 greet(user_name)  

if __name__ == "__main__":  
 main()  

% python func_arg.py  
Введіть ваше ім'я: Arjun  
Hello, Arjun!  
Друкуємо ім'я модуля з функції greet: __main__

Модуль

Модуль — це Python файл з розширенням .py, який призначений для імпорту в скрипти або інші модулі.
Це четверта історія та продовження нашої попередньої розповіді з серії про Python. У цій історії ми розглянемо наступні теми:

  • Простір імен
  • Скрипти
  • Модулі
  • Пакети

pic

Бібліотека -> Пакети -> Підпакети -> Модулі

Простір імен

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

В Python є кілька рівнів просторів імен:

  1. Глобальний простір імен: Це найвищий рівень простору імен для програми, що включає всі змінні та функції, визначені на глобальному рівні.
  2. Простір імен модуля: Кожен модуль має власний простір імен. Змінні, функції та класи, визначені в модулі, є частиною простору імен цього модуля.
  3. Простір імен функції: Коли ви визначаєте змінні або функції всередині функції, ці імена існують у власному локальному просторі імен функції.
  4. Вбудований простір імен: Python має вбудований простір імен для функцій та виключень (як-от print(), len(), Exception тощо).
% cat func_arg.py   
x = 100 # Глобальна змінна  

def my_function():  
 x = 10 # Локальна змінна  
 y = 20 # Локальна змінна  
 print(f"Локальний x всередині функції: {x}")  
 print(dir())  

my_function()  
print(f"Глобальний x поза функцією: {x}")  

print(dir())  

% python func_arg.py  
Локальний x всередині функції: 10  
['x', 'y']  
Глобальний x поза функцією: 100  
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'my_function', 'x']  



- Змінна x всередині my_function є локальною і існує тільки  
в межах області видимості функції (локальний простір імен).  

- x, визначена поза функцією, є глобальною змінною та є частиною  
глобального простору імен.  

- Коли викликається my_function(), друкується локальна змінна x (значення 10),  
але глобальна x (значення 100) залишається незмінною.

Функція dir() в Python використовується для повернення списку дійсних атрибутів (імен) для об'єкта. Вона може бути використана для перевірки атрибутів та методів об'єкта, модуля, класу чи вбудованого простору імен - dir([object]).

  • Якщо передано аргумент object, dir() повертає список атрибутів цього об'єкта.
  • Якщо аргумент не передано, функція повертає список імен в поточній області видимості (локальній або глобальній).

Python Скрипти

Python скрипт — це по суті Python програма, яка виконується безпосередньо інтерпретатором Python. Зазвичай це самостійні програми, які використовуються для автоматизації завдань або виконання специфічних операцій. __name__ — це спеціальна вбудована змінна в Python, яка вказує на ім'я модуля.

Характеристики Python скриптів:
Виконуваність: Скрипт зазвичай виконується безпосередньо через команду python, наприклад, python script.py.
Точка входу: В Python точка входу скрипту зазвичай визначається через конструкцію if __name__ == “__main__”:. Умова if __name__ == "__main__": дає значення True, і викликається функція main().
Якщо скрипт імпортується як модуль, name встановлюється на ім'я скрипта (наприклад, script).

% cat func_arg.py   
def greet(name):  
 print(f"Hello, {name}!")  
 print(f"Друкуємо ім'я модуля з функції greet: {__name__}")  

def main():  
 # Основна логіка програми  
 user_name = input("Введіть ваше ім'я: ")  
 greet(user_name)  

if __name__ == "__main__":  
 main()  

% python func_arg.py  
Введіть ваше ім'я: Arjun  
Hello, Arjun!  
Друкуємо ім'я модуля з функції greet: __main__

Модуль

Модуль — це Python файл з розширенням .py, який призначений для імпорту в скрипти або інші модулі.
Це дозволяє організувати наш код у кілька файлів для кращої підтримуваності, повторного використання та розподілу відповідальності.

Модуль — це Python файл з розширенням .py, який призначений для імпорту в скрипти або інші модулі. Модуль — це просто файл, що містить визначення Python, функції, класи та виконуваний код.

# Виконання наступного коду нічого не дасть. Тому це класифікується як модуль.  
cat module_add.py  
-------------  
def add (x,y):  
 return x+y  

--------######--------#######--------#######--------#######--------  
# Виконання наступного коду виконає функцію. Тому це класифікується як скрипт.  
cat script_add.py  
------------   
def add (x,y):  
 return x+y  
print(add (5,6))
% cat mymodule.py   
# mymodule.py  
def greet(name):  
 print(f"Hello, {name}!")  

class Person:  
 def __init__(self, name, age):  
 self.name = name  
 self.age = age  

 def introduce(self):  
 print(f"Hi, I'm {self.name} and I'm {self.age} years old.")  
print(f"I am from module: {__name__}")  

% cat main.py   
import mymodule  

mymodule.greet("Arjun")  

person = mymodule.Person("Bob", 30)  
person.introduce()  

# Виконання модуля як скрипту  
% python mymodule.py  
I am from module: __main__  

# Виклик модуля з скрипта  
% python main.py   
I am from module: mymodule  
Hello, Arjun!  
Hi, I'm Bob and I'm 30 years old.

Як імпортувати модуль

  1. Основний імпорт: Імпортуйте модуль в Python за допомогою інструкції import

__name__ — це спеціальна змінна, яка вказує на ім'я Python модуля, встановлене інтерпретатором. Якщо ваш модуль викликається як скрипт, то рядок ‘__main__’ автоматично буде призначений спеціальній змінній __name__. Але якщо ви імпортуєте модуль в інший модуль, рядок ‘moduleadd’ буде призначений `name_`.

% cat script_add.py   
import module_add  
module_add.author = "Aadya"  
print(f"Автор: {module_add.author}")  
print(module_add.add(5,6))  

% cat module_add.py   
import sys  
print(f"Імпортуємо модуль, ім'я встановлене інтерпретатором: {__name__}")  
author = "Arjun Pandey"  
def add (x,y):  
 print(f"Деталі модуля: {sys.modules[__name__]}")  
 return x+y  

% python script_add.py   
Імпортуємо модуль, ім'я встановлене інтерпретатором: module_add  
Автор: Aadya  
Деталі модуля:   
11

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

% cat module_add.py   
import sys  
print(f"Імпортуємо модуль, ім'я встановлене інтерпретатором: {__name__}")  
author = "Arjun Pandey"  
def add (x,y):  
 print(f"Деталі модуля: {sys.modules[__name__]}")  
 return x+y  

 % cat script_add.py   
from module_add import author, add  
print(f"Автор: {author}")  
print(add(5,6))  

% python script_add.py   
Імпортуємо модуль, ім'я встановлене інтерпретатором: module_add  
Автор: Arjun Pandey  
Деталі модуля:   
11

3. Імпорт з псевдонімом: Імпортуйте модуль та призначте псевдонім у Python

% cat module_add.py   
import sys  
print(f"Імпортуємо модуль, ім'я встановлене інтерпретатором: {__name__}")  
author = "Arjun Pandey"  
def add (x,y):  
 print(f"Деталі модуля: {sys.modules[__name__]}")  
 return x+y  

% cat script_add.py   
from module_add import author as auth, add as a  
print(f"Автор: {auth}")  
print(a(5,6))  

 % python script_add.py   
Імпортуємо модуль, ім'я встановлене інтерпретатором: module_add  
Автор: Arjun Pandey  
Деталі модуля:   
11

4. Імпортування всього за допомогою * в Python: Щоб імпортувати всі об'єкти (функції, змінні, класи тощо) з модуля, можна використати інструкцію import *.
Це дозволяє організувати наш код у кілька файлів для кращої підтримуваності, повторного використання та розподілу відповідальності.

Модуль — це Python файл з розширенням .py, який призначений для імпорту в скрипти або інші модулі. Модуль — це просто файл, що містить визначення Python, функції, класи та виконуваний код.

# Виконання наступного коду нічого не дасть. Тому це класифікується як модуль.  
cat module_add.py  
-------------  
def add (x,y):  
 return x+y  

--------######--------#######--------#######--------#######--------  
# Виконання наступного коду виконає функцію. Тому це класифікується як скрипт.  
cat script_add.py  
------------   
def add (x,y):  
 return x+y  
print(add (5,6))
% cat mymodule.py   
# mymodule.py  
def greet(name):  
 print(f"Hello, {name}!")  

class Person:  
 def __init__(self, name, age):  
 self.name = name  
 self.age = age  

 def introduce(self):  
 print(f"Hi, I'm {self.name} and I'm {self.age} years old.")  
print(f"I am from module: {__name__}")  

% cat main.py   
import mymodule  

mymodule.greet("Arjun")  

person = mymodule.Person("Bob", 30)  
person.introduce()  

# Виконання модуля як скрипту  
% python mymodule.py  
I am from module: __main__  

# Виклик модуля з скрипта  
% python main.py   
I am from module: mymodule  
Hello, Arjun!  
Hi, I'm Bob and I'm 30 years old.

Як імпортувати модуль

  1. Основний імпорт: Імпортуйте модуль в Python за допомогою інструкції import

__name__ — це спеціальна змінна, яка вказує на ім'я Python модуля, встановлене інтерпретатором. Якщо ваш модуль викликається як скрипт, то рядок ‘__main__’ автоматично буде призначений спеціальній змінній __name__. Але якщо ви імпортуєте модуль в інший модуль, рядок ‘moduleadd’ буде призначений `name_`.

% cat script_add.py   
import module_add  
module_add.author = "Aadya"  
print(f"Автор: {module_add.author}")  
print(module_add.add(5,6))  

% cat module_add.py   
import sys  
print(f"Імпортуємо модуль, ім'я встановлене інтерпретатором: {__name__}")  
author = "Arjun Pandey"  
def add (x,y):  
 print(f"Деталі модуля: {sys.modules[__name__]}")  
 return x+y  

% python script_add.py   
Імпортуємо модуль, ім'я встановлене інтерпретатором: module_add  
Автор: Aadya  
Деталі модуля:   
11

2. Вибірковий імпорт: Імпортуйте специфічні змінні/функції/класи. Ви можете імпортувати певну частину пакету або модуля за допомогою наступного синтаксису.

% cat module_add.py   
import sys  
print(f"Імпортуємо модуль, ім'я встановлене інтерпретатором: {__name__}")  
author = "Arjun Pandey"  
def add (x,y):  
 print(f"Деталі модуля: {sys.modules[__name__]}")  
 return x+y  

 % cat script_add.py   
from module_add import author, add  
print(f"Автор: {author}")  
print(add(5,6))  

% python script_add.py   
Імпортуємо модуль, ім'я встановлене інтерпретатором: module_add  
Автор: Arjun Pandey  
Деталі модуля:   
11

3. Імпорт з псевдонімом: Імпортуйте модуль та призначте псевдонім у Python

% cat module_add.py   
import sys  
print(f"Імпортуємо модуль, ім'я встановлене інтерпретатором: {__name__}")  
author = "Arjun Pandey"  
def add (x,y):  
 print(f"Деталі модуля: {sys.modules[__name__]}")  
 return x+y  

% cat script_add.py   
from module_add import author as auth, add as a  
print(f"Автор: {auth}")  
print(a(5,6))  

 % python script_add.py   
Імпортуємо модуль, ім'я встановлене інтерпретатором: module_add  
Автор: Arjun Pandey  
Деталі модуля:   
11

4. Імпортування всього за допомогою * в Python: Щоб імпортувати всі об'єкти (функції, змінні, класи тощо) з модуля, можна використати інструкцію import *.
В Python використання інструкції import * — тобто імпортування всього з модуля — загалом не рекомендується.

Проблеми з import *

Можливі конфлікти імен:

% cat module_a.py   
def greet():  
 print("Hello from module A!")  
% cat module_b.py   
def greet():  
 print("Hello from module B!")  
% cat main.py   
from module_a import *  
from module_b import *  
greet() # Яка функція greet буде викликана? Python використовуватиме останню імпортовану.  

 % python main.py   
Hello from module B!

Забруднення простору імен (Namespace Pollution): Коли ми використовуємо import *, ми імпортуємо всі функції, класи, змінні та об'єкти з модуля в поточний простір імен. Це означає, що будь-які функції, змінні чи об'єкти з модуля будуть доступні без префікса модуля.
- Можна ненавмисно перезаписати змінні або функції, які вже були визначені в скрипті.
- Це ускладнює читання та налагодження коду.

# module.py  
x = 42  
y = 100  

def print_x():  
 print(x)  

# main.py  
% cat main.py   
from module import * # Імпортує x, y та print_x() в глобальний простір імен  
print(x) # Без проблем, виводить 42  
print_x() # Без проблем, виводить 42  
x = 10 # Перезаписує x з модуля в головному просторі імен  
print_x() # Проблема, виводить 42 замість 20  
print(dir()) # Перевірка атрибутів в поточному просторі імен головного скрипту  
print(x) # Виводить 10  

% python main.py  
42  
42  
42  
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__',   
'__loader__', '__name__', '__package__', '__spec__', 'print_x', 'x', 'y']  
10
  • Важливо, що це присвоєння “x = 10” не впливає на x в module.py, який залишиться рівним 42. Змінна x в main.py тепер затінює x з module.py в межах main.py.
  • Однак це переназначення x не впливає на функцію print_x(), яка вже була імпортована з module.py.
  • Коли функція print_x() визначена в module.py, вона використовує змінну x в просторі імен модуля (яка дорівнює 42).
  • Навіть якщо ім'я x затінено в main.py, функція print_x() все одно використовує x з module.py, а не локальну змінну x в main.py.
  • Змінна x в main.py є окремою змінною і не перезаписує x в module.py для функцій, імпортованих з module.py.

Приватні методи та змінні: В Python приватні методи та змінні — це ті, що призначені для використання тільки всередині модуля або класу та часто позначаються за допомогою початкового підкреслення (_) або подвійного підкреслення (__) у назві змінної чи методу. Згідно з конвенцією, до них не повинно звертатися безпосередньо ззовні модуля або класу.

Однак Python не суворо контролює приватність (це конвенція, а не особливість мови), і ці змінні або методи все ще доступні. Але зазвичай вони призначені для внутрішнього використання.

  • Приватні методи та змінні (ті, що мають початкове підкреслення) не повинні імпортуватися безпосередньо за допомогою import *.
  • Якщо ви використовуєте import *, вони не будуть імпортовані, якщо не вказано явно в атрибуті __all__ модуля.
% cat module.py   
_priv_x = 100 # Приватна змінна  
def _secret(): # Приватна функція  
 print("This is a secret function.")  
pub_y = 10  

% cat main.py   
from module import _secret  
_secret()  
from module import * # Імпортує тільки публічні елементи, _x і _secret не імпортуються  
print(pub_y)  
print(_priv_x) # Викликає помилку NameError: name '_x' is not defined  

% python main.py  
This is a secret function.  
10  
Traceback (most recent call last):  
 File "/Users/arjunpandey/python/scrape/module-story/main.py", line 5, in   
 print(_priv_x) # Викликає помилку NameError: name '_x' is not defined  
 ^^^^^^^  
NameError: name '_priv_x' is not defined

__all__ і контроль імпорту:

Щоб явно контролювати, що імпортується за допомогою import *, модуль може визначити спеціальний список під назвою __all__.
В Python використання інструкції import * — тобто імпортування всього з модуля — загалом не рекомендується.

Проблеми з import *

Можливі конфлікти імен:

% cat module_a.py   
def greet():  
 print("Hello from module A!")  
% cat module_b.py   
def greet():  
 print("Hello from module B!")  
% cat main.py   
from module_a import *  
from module_b import *  
greet() # Яка функція greet буде викликана? Python використовуватиме останню імпортовану.  

 % python main.py   
Hello from module B!

Забруднення простору імен (Namespace Pollution): Коли ми використовуємо import *, ми імпортуємо всі функції, класи, змінні та об'єкти з модуля в поточний простір імен. Це означає, що будь-які функції, змінні чи об'єкти з модуля будуть доступні без префікса модуля.
- Можна ненавмисно перезаписати змінні або функції, які вже були визначені в скрипті.
- Це ускладнює читання та налагодження коду.

# module.py  
x = 42  
y = 100  

def print_x():  
 print(x)  

# main.py  
% cat main.py   
from module import * # Імпортує x, y та print_x() в глобальний простір імен  
print(x) # Без проблем, виводить 42  
print_x() # Без проблем, виводить 42  
x = 10 # Перезаписує x з модуля в головному просторі імен  
print_x() # Проблема, виводить 42 замість 20  
print(dir()) # Перевірка атрибутів в поточному просторі імен головного скрипту  
print(x) # Виводить 10  

% python main.py  
42  
42  
42  
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__',   
'__loader__', '__name__', '__package__', '__spec__', 'print_x', 'x', 'y']  
10
  • Важливо, що це присвоєння “x = 10” не впливає на x в module.py, який залишиться рівним 42. Змінна x в main.py тепер затінює x з module.py в межах main.py.
  • Однак це переназначення x не впливає на функцію print_x(), яка вже була імпортована з module.py.
  • Коли функція print_x() визначена в module.py, вона використовує змінну x в просторі імен модуля (яка дорівнює 42).
  • Навіть якщо ім'я x затінено в main.py, функція print_x() все одно використовує x з module.py, а не локальну змінну x в main.py.
  • Змінна x в main.py є окремою змінною і не перезаписує x в module.py для функцій, імпортованих з module.py.

Приватні методи та змінні: В Python приватні методи та змінні — це ті, що призначені для використання тільки всередині модуля або класу та часто позначаються за допомогою початкового підкреслення (_) або подвійного підкреслення (__) у назві змінної чи методу. Згідно з конвенцією, до них не повинно звертатися безпосередньо ззовні модуля або класу.

Однак Python не суворо контролює приватність (це конвенція, а не особливість мови), і ці змінні або методи все ще доступні. Але зазвичай вони призначені для внутрішнього використання.

  • Приватні методи та змінні (ті, що мають початкове підкреслення) не повинні імпортуватися безпосередньо за допомогою import *.
  • Якщо ви використовуєте import *, вони не будуть імпортовані, якщо не вказано явно в атрибуті __all__ модуля.
% cat module.py   
_priv_x = 100 # Приватна змінна  
def _secret(): # Приватна функція  
 print("This is a secret function.")  
pub_y = 10  

% cat main.py   
from module import _secret  
_secret()  
from module import * # Імпортує тільки публічні елементи, _x і _secret не імпортуються  
print(pub_y)  
print(_priv_x) # Викликає помилку NameError: name '_x' is not defined  

% python main.py  
This is a secret function.  
10  
Traceback (most recent call last):  
 File "/Users/arjunpandey/python/scrape/module-story/main.py", line 5, in   
 print(_priv_x) # Викликає помилку NameError: name '_x' is not defined  
 ^^^^^^^  
NameError: name '_priv_x' is not defined

__all__ і контроль імпорту:

Щоб явно контролювати, що імпортується за допомогою import *, модуль може визначити спеціальний список під назвою __all__.
Цей список містить імена всіх об'єктів, які повинні вважатися публічними і доступними для імпорту, коли використовується from module import *.

  • Якщо в модулі визначено __all__, то будуть імпортовані лише імена, зазначені в __all__, незалежно від того, чи мають вони початкове підкреслення чи ні.
  • Якщо __all__ не визначено, імпортуються всі імена, які не починаються з підкреслення (_).
% cat main.py   
from module import * # Імпортуються тільки публічні елементи, _x і _secret виключені  
_secret()  
print(pub_y) # Викликає помилку NameError: name 'pub_y' is not defined  
print(_priv_x)   

% cat module.py   
__all__ = ['_priv_x','_secret'] # pub_y не включено до списку публічних об'єктів  
_priv_x = 100 # Приватна змінна  
def _secret(): # Приватна функція  
 print("This is a secret function.")  
pub_y = 10  

% python main.py  
This is a secret function.  
Traceback (most recent call last):  
 File "/Users/arjunpandey/python/scrape/module-story/main.py", line 3, in   
 print(pub_y)  
 ^^^^^  
NameError: name 'pub_y' is not defined

Бібліотеки Python

Бібліотеки використовуються для розширення функціональності Python без необхідності переписувати звичайні функції з нуля. Бібліотека Python може містити:

  1. Модулі: Модуль — це окремий файл Python, часто реалізуючий конкретну функціональність або можливість.
  2. Пакети: Пакет — це каталог, який містить кілька модулів і файл __init__.py, щоб вказати, що це пакет.
  3. Підпакети: Пакет може містити інші пакети всередині себе, що веде до ієрархії модулів і пакетів.

Бібліотека Python може бути як один модуль, так і велика колекція модулів та підпакетів.

Модулі стандартної бібліотеки Python

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

% cat main.py   
import math  
from datetime import datetime  
import os  
print(math.sqrt(16)) # Вивід: 4.0  
now = datetime.now()  
print(now)  
print(os.getcwd()) # Отримання поточної робочої директорії  

% python main.py  
4.0  
2024-12-29 10:58:31.594759  
/Users/arjunpandey/python/scrape/module-story

Шлях пошуку модулів (sys.path)

Python шукає модулі в списку директорій.
Цей список містить імена всіх об'єктів, які повинні вважатися публічними і доступними для імпорту, коли використовується from module import *.

  • Якщо в модулі визначено __all__, будуть імпортовані лише імена, зазначені в __all__, незалежно від того, чи мають вони початкове підкреслення чи ні.
  • Якщо __all__ не визначено, імпортуються всі імена, які не починаються з підкреслення (_).
% cat main.py   
from module import * # Імпортуються тільки публічні елементи, _x і _secret виключені  
_secret()  
print(pub_y) # Викликає помилку NameError: name 'pub_y' is not defined  
print(_priv_x)   

% cat module.py   
__all__ = ['_priv_x','_secret'] # pub_y не включено до списку публічних об'єктів  
_priv_x = 100 # Приватна змінна  
def _secret(): # Приватна функція  
 print("This is a secret function.")  
pub_y = 10  

% python main.py  
This is a secret function.  
Traceback (most recent call last):  
 File "/Users/arjunpandey/python/scrape/module-story/main.py", line 3, in   
 print(pub_y)  
 ^^^^^  
NameError: name 'pub_y' is not defined

Бібліотека Python

Бібліотеки використовуються для розширення функціональності Python без необхідності переписувати звичайні функції з нуля. Бібліотека Python може містити:

  1. Модулі: Модуль — це окремий файл Python, який часто реалізує конкретну функціональність або можливість.
  2. Пакети: Пакет — це каталог, що містить кілька модулів і файл __init__.py, щоб вказати, що це пакет.
  3. Підпакети: Пакет може містити інші пакети всередині себе, що створює ієрархію модулів і пакетів.

Бібліотека Python може бути одним модулем або великою колекцією модулів та підпакетів.

Модулі стандартної бібліотеки Python

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

% cat main.py   
import math  
from datetime import datetime  
import os  
print(math.sqrt(16)) # Вивід: 4.0  
now = datetime.now()  
print(now)  
print(os.getcwd()) # Отримати поточну робочу директорію  

% python main.py  
4.0  
2024-12-29 10:58:31.594759  
/Users/arjunpandey/python/scrape/module-story

Шлях пошуку модулів (sys.path)

Python шукає модулі в списку директорій.
Цей список зберігається в sys.path, який ініціалізується при запуску Python.

  • Якщо ви імпортуєте модуль, Python шукає його в директоріях, зазначених у sys.path.
  • Ви можете додавати директорії до sys.path під час виконання, використовуючи sys.path.append():
% cat main.py   
import sys  
print(sys.path)  
sys.path.append('/Users/arjunpandey/python/scrape/')  
import func_arg  
func_arg.greet("Arjun")  

% cat /Users/arjunpandey/python/scrape/func_arg.py   
def greet(name):  
 print(f"Hello, {name}!")  
 print(f"Printing Name of the module from function greet: {__name__}")  

def main():  
 # Основна логіка програми  
 user_name = input("Enter your name: ")  
 greet(user_name)  

if __name__ == "__main__":  
 main()  
%  


% python main.py  
['/Users/arjunpandey/python/scrape/module-story', '/Library/Frameworks/Python.framework/Versions/3.12/lib/python312.zip', '/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12', '/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/lib-dynload', '/Users/arjunpandey/python/project-x/lib/python3.12/site-packages']  
Hello, Arjun!  
Printing Name of the module from function greet: func_arg

Динамічний імпорт

Ми можемо динамічно імпортувати модулі за допомогою модуля importlib, що корисно, коли ми не знаємо, який модуль потрібно імпортувати під час компіляції.

% cat main.py   
import importlib  
import os  

def load_plugin(plugin_name):  
 try:  
 plugin = importlib.import_module(f"plugins.{plugin_name}")  
 plugin.run() # Припускаємо, що кожен плагін має функцію `run()`  
 except ModuleNotFoundError:  
 print(f"Plugin {plugin_name} not found.")  

if __name__ == "__main__":  
 plugin_name = input("Enter the plugin to load (plugin_a/plugin_b): ").strip()  
 load_plugin(plugin_name)  

% cat plugins/plugin_a.py   
# plugin_a.py  
def run():  
 print("Plugin A is running!")  

% cat plugins/plugin_b.py   
# plugin_b.py  
def run():  
 print("Plugin B is running!")  


% python main.py   
Enter the plugin to load (plugin_a/plugin_b): plugin_a  
Plugin A is running!  

% python main.py  
Enter the plugin to load (plugin_a/plugin_b): plugin_b  
Plugin B is running!

Імпорт непотрібних модулів або імпорт усіх модулів

Збільшене використання пам'яті: Python завантажує весь модуль у пам'ять. Якщо ви імпортуєте всі модулі в великому пакеті або імпортуєте модулі, які не використовуєте, ви витрачаєте ресурси пам'яті.
Приклад: import pandas # імпортує всю бібліотеку pandas (дуже велику)

Повільний час запуску: Кожного разу, коли модуль імпортується, Python повинен завантажити його з диска, виконати ініціалізаційний код (включаючи визначення функцій та класів) і зберегти його в пам'яті. Імпорт великої кількості непотрібних модулів може значно уповільнити час запуску вашого застосунку.
Приклад: Якщо нашому скрипту потрібна лише невелика частина цих бібліотек (скажімо, лише os і time), Python все одно має завантажити та ініціалізувати всі інші модулі. Це збільшує час запуску скрипту і може стати помітним у великих застосунках.
import os
import time
import logging
import math
import numpy
import pandas # велика бібліотека

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

Неекономне використання дискового вводу/виводу
Збільшений ризик циклів імпортів
Великі Docker-образи або віртуальні середовища
Ризик конфліктів чи зіткнень в просторах імен

Пакет Python

Пакет Python — це каталог, який містить кілька модулів Python і може також містити інші підпакети. В Python існують два основних типи пакетів: Namespace Packages та Traditional Packages.
Цей список зберігається в sys.path, який ініціалізується при запуску Python.

  • Якщо ви імпортуєте модуль, Python шукає його в директоріях, зазначених у sys.path.
  • Ви можете додавати директорії до sys.path під час виконання, використовуючи sys.path.append():
% cat main.py   
import sys  
print(sys.path)  
sys.path.append('/Users/arjunpandey/python/scrape/')  
import func_arg  
func_arg.greet("Arjun")  

% cat /Users/arjunpandey/python/scrape/func_arg.py   
def greet(name):  
 print(f"Hello, {name}!")  
 print(f"Printing Name of the module from function greet: {__name__}")  

def main():  
 # Основна логіка програми  
 user_name = input("Enter your name: ")  
 greet(user_name)  

if __name__ == "__main__":  
 main()  
%  


% python main.py  
['/Users/arjunpandey/python/scrape/module-story', '/Library/Frameworks/Python.framework/Versions/3.12/lib/python312.zip', '/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12', '/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/lib-dynload', '/Users/arjunpandey/python/project-x/lib/python3.12/site-packages']  
Hello, Arjun!  
Printing Name of the module from function greet: func_arg

Динамічний імпорт

Ми можемо динамічно імпортувати модулі за допомогою модуля importlib, що корисно, коли ми не знаємо, який модуль потрібно імпортувати під час компіляції.

% cat main.py   
import importlib  
import os  

def load_plugin(plugin_name):  
 try:  
 plugin = importlib.import_module(f"plugins.{plugin_name}")  
 plugin.run() # Припускаємо, що кожен плагін має функцію `run()`  
 except ModuleNotFoundError:  
 print(f"Plugin {plugin_name} not found.")  

if __name__ == "__main__":  
 plugin_name = input("Enter the plugin to load (plugin_a/plugin_b): ").strip()  
 load_plugin(plugin_name)  

% cat plugins/plugin_a.py   
# plugin_a.py  
def run():  
 print("Plugin A is running!")  

% cat plugins/plugin_b.py   
# plugin_b.py  
def run():  
 print("Plugin B is running!")  


% python main.py   
Enter the plugin to load (plugin_a/plugin_b): plugin_a  
Plugin A is running!  

% python main.py  
Enter the plugin to load (plugin_a/plugin_b): plugin_b  
Plugin B is running!

Імпорт непотрібних модулів або імпорт всіх модулів

Збільшене використання пам'яті: Python завантажує весь модуль у пам'ять. Якщо ви імпортуєте всі модулі великого пакету або імпортуєте модулі, які насправді не використовуєте, ви витрачаєте ресурси пам'яті.
Приклад: import pandas # імпортує всю бібліотеку pandas (дуже велику)

Повільний час запуску: Кожного разу, коли модуль імпортується, Python має завантажити його з диска, виконати ініціалізаційний код (включаючи визначення функцій та класів) і зберегти його в пам'яті. Імпортування великої кількості непотрібних модулів може значно уповільнити час запуску вашої програми.
Приклад: Якщо нашому скрипту потрібна лише невелика частина цих бібліотек (наприклад, тільки os і time), Python все одно має завантажити та ініціалізувати всі інші модулі. Це збільшує час, необхідний для запуску скрипту, і може стати помітним у більших програмах.
import os
import time
import logging
import math
import numpy
import pandas # велика бібліотека

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

Неекономне використання дискового вводу/виводу
Збільшений ризик циклічних імпортів
Великі Docker-образи або віртуальні середовища
Ризик конфліктів просторів імен

Пакет Python

Пакет Python — це каталог, що містить кілька модулів Python і може також містити інші підпакети. В Python існують два основних типи пакетів: Namespace Packages та Traditional Packages.
Обидва типи служать для організації модулів Python, але мають різну поведінку та структуру.

Модуль — це один файл, що містить Python код, тоді як пакет — це колекція пов'язаних між собою модулів, організованих у вигляді структури директорій.

Пакет Namespace

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

Пакет namespace — це тип пакету, для якого не потрібен файл __init__.py. Замість цього Python автоматично об'єднує всі директорії, що належать до одного простору імен. Це особливо корисно для розподілу великих пакетів або систем, заснованих на плагінах. Завдяки пакетам namespace можна розділити пакет на кілька директорій, причому кожна з них може знаходитися в різному місці.

% cat /Users/arjunpandey/python/scrape/random/ext_project/core/db.py  
def func():  
 print("This is function from core.db")  
(project-x) arjunpandey@Arjuns-MacBook-Pro app % cat /Users/arjunpandey/python/scrape/pkgstory/ext_project/core/module_a.py   
# core/module_a.py  
def func():  
 print("This is function from core.module_a")  

(project-x) arjunpandey@Arjuns-MacBook-Pro app % cat /Users/arjunpandey/python/scrape/pkgstory/ext_project/plugin/module_b.py   
# plugin/module_b.py  
def func():  
 print("This is function from plugin.module_b")  

% cat main.py   
import sys  
sys.path.append('/Users/arjunpandey/python/scrape/pkgstory/ext_project')  
sys.path.append('/Users/arjunpandey/python/scrape/random/ext_project')  
# main.py  
import core.module_a  
import plugin.module_b  
import core.db  
import lib.lib  
core.module_a.func() # Output: This is function from core.module_a  
plugin.module_b.func() # Output: This is function from plugin.module_b  
core.db.func() # This is function from core.db   
lib.lib.func() # This is function from lib.lib  

app % cat lib/lib.py   
def func():  
 print("This is function from lib.lib")  

% python main.py  
This is function from core.module_a  
This is function from plugin.module_b  
This is function from core.db  
This is function from lib.lib
  • ext-project: Це каталог і представляє пакет namespace.
  • core: Це підкаталог в межах ext-project. Він не потребує файлу __init__.py, оскільки ext-project є пакетом namespace.
  • module_a.py: Це Python файл (модуль) всередині каталогу core. Він містить функції, класи або інший Python код.

Додавання підмодулю
. secret.py знаходиться в іншій директорії, доданій до sys.path, переконайтеся, що використовуєте абсолютний імпорт (абсолютний шлях від директорії програми) — lib/secret.py або з директорії lib: from lib.secret import або from .secret import *
. Якщо ми використовуємо явний імпорт, нам не потрібно використовувати список __all__.

# У наведеному коді ми робимо явний/вибірковий імпорт.  
# Не потрібно використовувати список __all__.
Обидва служать для організації модулів Python, але мають різну поведінку та структуру.

**Модуль** — це один файл, що містить Python код, тоді як **пакет** — це колекція пов'язаних модулів, організованих у вигляді структури директорій.

## Пакет Namespace

У Python **пакети namespace** дозволяють одному логічному пакету охоплювати кілька директорій на файловій системі. Ця можливість особливо корисна для великих програм або модульних систем, де компоненти одного пакету можуть бути розподілені по різних директоріях або навіть різних проектах Python.

**Пакет namespace** — це тип пакету, для якого не потрібен файл `__init__.py`. Замість цього Python автоматично об'єднує всі директорії, що належать до одного простору імен. Це особливо корисно для розподілу великих пакетів або систем, заснованих на плагінах. Завдяки пакетам namespace можна розділити пакет на кілька директорій, причому кожна з них може знаходитися в різному місці.

% cat /Users/arjunpandey/python/scrape/random/extproject/core/db.py
def func():
print("This is function from core.db")
(project-x) arjunpandey@Arjuns-MacBook-Pro app % cat /Users/arjunpandey/python/scrape/pkgstory/ext
project/core/module_a.py

core/module_a.py

def func():
print("This is function from core.module_a")

(project-x) arjunpandey@Arjuns-MacBook-Pro app % cat /Users/arjunpandey/python/scrape/pkgstory/extproject/plugin/moduleb.py

plugin/module_b.py

def func():
print("This is function from plugin.module_b")

% cat main.py
import sys
sys.path.append('/Users/arjunpandey/python/scrape/pkgstory/extproject')
sys.path.append('/Users/arjunpandey/python/scrape/random/ext
project')

main.py

import core.modulea
import plugin.module
b
import core.db
import lib.lib
core.modulea.func() # Output: This is function from core.modulea
plugin.moduleb.func() # Output: This is function from plugin.moduleb
core.db.func() # This is function from core.db
lib.lib.func() # This is function from lib.lib

app % cat lib/lib.py
def func():
print("This is function from lib.lib")

% python main.py
This is function from core.modulea
This is function from plugin.module
b
This is function from core.db
This is function from lib.lib
```

  • ext-project: Це каталог і представляє пакет namespace.
  • core: Це підкаталог всередині ext-project. Він не потребує файлу __init__.py, оскільки ext-project є пакетом namespace.
  • module_a.py: Це Python файл (модуль) всередині каталогу core. Він містить функції, класи або інший Python код.

Додавання підмодуля
. secret.py знаходиться в іншій директорії, доданій до sys.path, переконайтеся, що використовуєте абсолютний імпорт (абсолютний шлях від директорії програми) — lib/secret.py або з директорії lib: from lib.secret import або from .secret import *
. Якщо ми використовуємо явний імпорт, нам не потрібно використовувати список __all__.

# У наведеному коді ми робимо явний/вибірковий імпорт.  
# Не потрібно використовувати список __all__.
% cat lib/lib.py  

from lib.secret import _secret_key, _access_key  
def func():  
 print("This is function from lib.lib")  
print(f"Secret and Access* {_secret_key} {_access_key}")
# Ми використовуємо імпорт *, тому нам потрібен список __all__   
app % cat lib/secret.py   
__all__ = ['_secret_key', '_access_key','info']  
info="Entering to DevOps"  
_secret_key="AWSYEKIAMOK"  
_access_key="SUMECONBETO23498KEY"  

app % cat lib/lib.py   
from lib.secret import * # або from .secret import *  
def func():  
 print("This is function from lib.lib")  
print(f"Secret and Access: {_secret_key} {_access_key}")  

 % cat main.py   
import sys  
sys.path.append('/Users/arjunpandey/python/scrape/pkgstory/ext_project')  
sys.path.append('/Users/arjunpandey/python/scrape/random/ext_project')  
# main.py  
import core.module_a  
import plugin.module_b  
import core.db  
import lib.lib  
core.module_a.func() # Вивід: This is function from core.module_a  
plugin.module_b.func() # Вивід: This is function from plugin.module_b  
core.db.func() # This is function from core.db   
lib.lib.func() # This is functionn from lib.lib  
print(lib.secret.info)  

####Оскільки ми вже імпортували модуль secret у lib.py, нам не потрібно імпортувати його знову у main.py  

% python main.py   
Secret and Access: AWSYEKIAMOK SUMECONBETO23498KEY  
This is function from core.module_a  
This is function from plugin.module_b  
This is function from core.db  
This is function from lib.lib  
Entering to DevOps

Традиційний пакет

Традиційний пакет у Python відноситься до структури директорії, яка містить колекцію модулів і, можливо, підмодулів. Кожен пакет зазвичай містить файл __init__.py, що робить директорію дійсним пакетом Python і дозволяє імпортувати його вміст структуровано.

  • Каталог пакету: Пакет представляється директорією, що містить один або кілька Python файлів (.py).
  • __init__.py: Цей файл необхідний для позначення директорії як пакету Python. Він виконується під час імпорту пакету або будь-якого з його модулів. Він може бути порожнім або містити ініціалізаційний код.
  • Модулі: Python файли всередині пакету називаються модулями. Ці модулі можуть містити функції, класи та змінні.
  • Підпакети: Пакет може також містити підпакети, які є власними директоріями, що містять файл __init__.py.

Я все ще намагаюся зрозуміти, як назвати приклад нижче. Особисто я вважаю його пакетом namespace, але деякі стверджують, що це просто традиційний пакет, в якому я видалив файл __init__.py. Які твої думки з цього приводу? 🤪

lib — це пакет верхнього рівня.

db — це підпакет всередині lib.

Нам не потрібно використовувати `__init__.py` у наведеному випадку, оскільки це схоже на пакет на основі простору імен.
% cat lib/lib.py  

from lib.secret import _secret_key, _access_key  
def func():  
 print("This is function from lib.lib")  
print(f"Secret and Access* {_secret_key} {_access_key}")
# Ми використовуємо імпорт *, тому нам потрібен список __all__   
app % cat lib/secret.py   
__all__ = ['_secret_key', '_access_key','info']  
info="Entering to DevOps"  
_secret_key="AWSYEKIAMOK"  
_access_key="SUMECONBETO23498KEY"  

app % cat lib/lib.py   
from lib.secret import * # або from .secret import *  
def func():  
 print("This is function from lib.lib")  
print(f"Secret and Access: {_secret_key} {_access_key}")  

 % cat main.py   
import sys  
sys.path.append('/Users/arjunpandey/python/scrape/pkgstory/ext_project')  
sys.path.append('/Users/arjunpandey/python/scrape/random/ext_project')  
# main.py  
import core.module_a  
import plugin.module_b  
import core.db  
import lib.lib  
core.module_a.func() # Вивід: This is function from core.module_a  
plugin.module_b.func() # Вивід: This is function from plugin.module_b  
core.db.func() # This is function from core.db   
lib.lib.func() # This is functionn from lib.lib  
print(lib.secret.info)  

####Оскільки ми вже імпортували модуль secret у lib.py, нам не потрібно імпортувати його знову у main.py  

% python main.py   
Secret and Access: AWSYEKIAMOK SUMECONBETO23498KEY  
This is function from core.module_a  
This is function from plugin.module_b  
This is function from core.db  
This is function from lib.lib  
Entering to DevOps

Традиційний пакет

Традиційний пакет у Python відноситься до структури директорії, яка містить колекцію модулів і, можливо, підмодулів. Кожен пакет зазвичай містить файл __init__.py, що робить директорію дійсним пакетом Python і дозволяє імпортувати його вміст структуровано.

  • Каталог пакету: Пакет представляється директорією, що містить один або кілька Python файлів (.py).
  • __init__.py: Цей файл необхідний для позначення директорії як пакету Python. Він виконується під час імпорту пакету або будь-якого з його модулів. Він може бути порожнім або містити ініціалізаційний код.
  • Модулі: Python файли всередині пакету називаються модулями. Ці модулі можуть містити функції, класи та змінні.
  • Підпакети: Пакет може також містити підпакети, які є власними директоріями, що містять файл __init__.py.

Я все ще намагаюся зрозуміти, як назвати приклад нижче. Особисто я вважаю його пакетом namespace, але деякі стверджують, що це просто традиційний пакет, в якому я видалив файл __init__.py. Які твої думки з цього приводу? 🤪

lib — це пакет верхнього рівня.

db — це підпакет всередині lib.

Нам не потрібно використовувати `__init__.py` у наведеному випадку, оскільки це схоже на пакет на основі простору імен.
lib/  
 module_a.py # Модуль у пакеті  
 module_b.py # Інший модуль  
 db/  
 db.py # Підпакет у пакеті lib  

tradition % cat main.py   
import lib.module_a  
import lib.module_b  
import lib.db.db  
lib.module_a.func()  
lib.module_a.func()  
lib.db.db.func()  

 % cat lib/*.py   
# lib/module_a.py  
def func():  
 print("This is function from lib/module_a")  

# lib/module_b.py  
def func():  
 print("This is function from lib/module_b")  

% cat lib/db/db.py   
def func():  
 print("This is function from lib/db/db")  

tradition % python main.py   
This is function from lib/module_a  
This is function from lib/module_a  
This is function from lib/db/db

Перетворення на Традиційний пакет

Використання вибіркового імпорту: Ми можемо бачити функції окремих модулів.

% cat main.py   
import lib  
lib.module_a.func()  
lib.module_b.func()  
lib.db.db.func()  

% cat lib/__init__.py   
from .module_a import func  
from .module_b import func  
from .db.db import func  

% cat lib/db/__init__.py   
from .db import func  
(project-x) arjunpandey@Arjuns-MacBook-Pro tradition %   


% python main.py  
This is function from lib/module_a  
This is function from lib/module_b  
This is function from lib/db/db

*Використання імпорту **

# За умовчанням викликається остання імпортована функція  
% cat main.py   
from lib import *  
func()  

 % python main.py  
This is function from lib/db/db  

---------------------------------------  
# Щоб явно викликати функцію іншого модуля, використовуйте наступний формат  

% cat main.py   
from lib import *  
module_b.func() # Останній імпортований модуль має пріоритет, щоб викликати конкретно module_b.func()   
func()  
% python main.py  
This is function from lib/module_b  
This is function from lib/db/db

pic

Різниця між Namespace та Звичайними пакетами

Знайшли щось неправильне/неправильно подане в статті? Вибачте!! Будь ласка, допоможіть мені виправити це якомога швидше 🙇‍♂️

Думки/пропозиції, висловлені в цій та будь-яких попередніх історіях, є виключно моїми і не мають відношення до інших….
lib/
modulea.py # Модуль у пакеті
module
b.py # Інший модуль
db/
db.py # Підпакет у пакеті lib

tradition % cat main.py
import lib.modulea
import lib.module
b
import lib.db.db
lib.modulea.func()
lib.module
a.func()
lib.db.db.func()

% cat lib/*.py

lib/module_a.py

def func():
print("This is function from lib/module_a")

lib/module_b.py

def func():
print("This is function from lib/module_b")

% cat lib/db/db.py
def func():
print("This is function from lib/db/db")

tradition % python main.py
This is function from lib/modulea
This is function from lib/module
a
This is function from lib/db/db
```

Перетворення на Традиційний пакет

Використання вибіркового імпорту: Ми можемо бачити функції окремих модулів.

% cat main.py   
import lib  
lib.module_a.func()  
lib.module_b.func()  
lib.db.db.func()  

% cat lib/__init__.py   
from .module_a import func  
from .module_b import func  
from .db.db import func  

% cat lib/db/__init__.py   
from .db import func  
(project-x) arjunpandey@Arjuns-MacBook-Pro tradition %   


% python main.py  
This is function from lib/module_a  
This is function from lib/module_b  
This is function from lib/db/db

*Використання імпорту **

# За умовчанням викликається остання імпортована функція  
% cat main.py   
from lib import *  
func()  

 % python main.py  
This is function from lib/db/db  

---------------------------------------  
# Щоб явно викликати функцію іншого модуля, використовуйте наступний формат  

% cat main.py   
from lib import *  
module_b.func() # Останній імпортований модуль має пріоритет, щоб викликати конкретно module_b.func()   
func()  
% python main.py  
This is function from lib/module_b  
This is function from lib/db/db

pic

Різниця між Namespace та Звичайними пакетами

Знайшли щось неправильне/неправильно подане в статті? Вибачте!! Будь ласка, допоможіть мені виправити це якомога швидше 🙇‍♂️

Думки/пропозиції, висловлені в цій та будь-яких попередніх історіях, є виключно моїми і не мають відношення до інших….

Перекладено з: Entering into DevOps-37 Python04

Leave a Reply

Your email address will not be published. Required fields are marked *