Сегодня мы поговорим о важной теме в Python — импортировании модулей. Это ключевая часть работы с кодом, которая позволяет нам организовывать и переиспользовать код в наших проектах.
В этой части лекции мы затронем:
- Ключевые слова
from,import, иas. - Абсолютные и относительные импорты.
- Роль файлов
__init__.py. - Специфичное значение конструкции
if __name__ == '__main__':.
Модуль в Python — это файл, содержащий определения и инструкции Python. Модули позволяют организовывать код в логически связные части, упрощая его поддержку и переиспользование. Каждый модуль имеет свой собственный пространственный контекст, что позволяет избегать конфликтов имен.
-
Модуль как файл:
- Любой файл с расширением
.pyявляется модулем. - Имя модуля соответствует имени файла.
Например, файл
math_operations.pyявляется модулемmath_operations. - Любой файл с расширением
-
Определения в модуле:
- Модуль может содержать функции, классы, переменные, а также исполняемый код.
# math_operations.py def add(a, b): return a + b def subtract(a, b): return a - b pi = 3.14159
-
Импортирование модулей:
- Вы можете импортировать модуль, используя ключевое слово
import.
import math_operations print(math_operations.add(5, 3)) # Вывод: 8 print(math_operations.pi) # Вывод: 3.14159
- Вы можете импортировать модуль, используя ключевое слово
-
Использование ключевых слов
fromиimport:- Вы можете импортировать конкретные функции или переменные из модуля.
from math_operations import add, pi print(add(5, 3)) # Вывод: 8 print(pi) # Вывод: 3.14159
-
Псевдонимы с использованием ключевого слова
as:- Вы можете использовать псевдонимы для импортированных модулей или их частей.
import math_operations as mo print(mo.add(5, 3)) # Вывод: 8
Пакет в Python — это коллекция модулей, организованных в директорию, которая содержит файл __init__.py. Пакеты
позволяют создавать иерархию модулей, упрощая организацию больших проектов.
Пример структуры пакета:
project/
├── package/
│ ├── __init__.py
│ ├── module1.py
│ └── module2.py
└── main.py
В файле __init__.py можно инициализировать пакет и упростить импорт модулей (хотя это совершенно не обязательно):
# package/__init__.py
from .module1 import function1
from .module2 import function2Теперь вы можете импортировать функции напрямую из пакета:
# main.py
from package import function1, function2
function1()
function2()-
Повторное использование кода:
- Модули позволяют переиспользовать код в разных частях проекта или в других проектах.
-
Организация кода:
- Модули и пакеты помогают структурировать проект, делая его более понятным и легким в поддержке.
-
Разделение пространства имен:
- Каждый модуль имеет свое собственное пространство имен, что позволяет избегать конфликтов имен.
-
Публичные и приватные части:
- В модуле можно указать, какие части должны быть доступны извне, а какие — нет. Для этого используется соглашение
об именовании: имена, начинающиеся с одного подчеркивания
_, считаются приватными.
# example.py def public_function(): pass def _private_function(): pass
- В модуле можно указать, какие части должны быть доступны извне, а какие — нет. Для этого используется соглашение
об именовании: имена, начинающиеся с одного подчеркивания
Python предоставляет несколько ключевых слов для импортирования модулей и их частей. Давайте рассмотрим их подробнее.
Ключевое слово import используется для импортирования всего модуля. Когда вы импортируете модуль таким образом, вы
можете обращаться к его содержимому, используя точечную нотацию.
Кроме вашего написанного кода, внутри python существуют сотни если не тысячи дополнительных модулей которые можно импортировать.
Какие-то из них используются постоянно, какие-то вы не увидите никогда.
Кроме того, можно установить еще тысячи, если не десятки тысяч готовых модулей, но об этом будет отдельная лекция
Пример:
import math
print(math.sqrt(16)) # Вывод: 4.0Ключевое слово from используется для импортирования конкретных частей модуля. Это позволяет вам импортировать только
те функции, классы или переменные, которые вам нужны.
Пример:
from math import sqrt
print(sqrt(16)) # Вывод: 4.0Ключевое слово as позволяет вам дать импортированному модулю или его части псевдоним. Это может быть полезно для
сокращения длинных имен или разрешения конфликтов имен (например, когда в разных модулях есть функции с одинаковыми
названиями).
Пример:
import math as m
print(m.sqrt(16)) # Вывод: 4.0Или в сочетании с from:
from math import sqrt as square_root
print(square_root(16)) # Вывод: 4.0Абсолютные импорты — это способ импортирования модулей, используя полный путь к модулю от корневого пакета. Они делают ваш код более читаемым и ясным.
Пример:
Предположим, у нас есть следующая структура каталогов:
project/
├── main.py
├── package_a/
│ └── __init__.py
│ └── foo.py
└── package_b/
└── __init__.py
└── bar.py
В файле foo.py мы можем импортировать функцию из bar.py таким образом:
# module_a/foo.py
from package_b.bar import some_functionВ этом примере мы используем абсолютный импорт, указывая полный путь от корня проекта (package_b.bar).
Относительные импорты используются для импортирования модулей относительно текущего модуля или пакета. Это удобный способ, когда нужно импортировать модули, находящиеся в том же пакете или соседних пакетах.
Пример:
В файле foo.py, чтобы импортировать модуль bar из того же пакета package_a, мы можем использовать относительный
импорт:
# package_a/foo.py
from .bar import some_functionЗдесь . означает текущий пакет. Для импорта модуля из родительского пакета используем ..:
# module_a/foo.py
from ..package_b.bar import some_functionФайлы __init__.py используются для обозначения директорий как пакетов Python. Эти файлы могут быть пустыми, но их
присутствие сигнализирует интерпретатору Python, что директория должна рассматриваться как пакет.
Примеры использования __init__.py:
- Пустой
__init__.py: Простой способ указать, что директория является пакетом. - С кодом: Вы можете включить код в
__init__.py, чтобы инициализировать пакет, настроить логирование или импортировать часто используемые подмодули:
# module_a/__init__.py
from .foo import FooClass
from .bar import BarClassТеперь при импорте module_a можно напрямую обращаться к FooClass и BarClass:
from module_a import FooClass, BarClassВ Python специальная переменная __name__ содержит имя текущего модуля. Когда скрипт запускается как основная
программа, __name__ имеет значение '__main__'. Это позволяет писать код, который будет выполняться только в случае,
если скрипт запущен напрямую, а не импортирован как модуль.
Пример:
Создадим файл example.py:
# example.py
def main():
print("Это главный скрипт.")
if __name__ == '__main__':
main()Если вы запустите example.py, вы увидите вывод "Это главный скрипт.". Но если вы импортируете этот файл как модуль в
другом скрипте:
# another_script.py
import exampleНикакой вывод не произойдет, так как main() не будет вызван.
Используем для того что бы отделить между собой основной файл и второстепенные модули
Python — это мощный язык программирования с богатой стандартной библиотекой, включающей множество встроенных модулей. Эти модули предоставляют функции и классы для выполнения широкого круга задач, от работы с системой и файловой системой до математических операций и генерации случайных чисел.
Стандартной библиотекой называются те пакеты которые не требуют дополнительной установки, и поставляются сразу вместе
с языком программирования.
Сегодня мы рассмотрим некоторые из наиболее часто используемых встроенных модулей в Python:
sys,os,math,random,collections,datetime, иitertools.
Модуль sys предоставляет доступ к некоторым переменным, используемым или поддерживаемым интерпретатором Python, а
также к функциям, которые взаимодействуют с ним.
Примеры:
import sys
# Получить аргументы командной строки
print("Аргументы командной строки:", sys.argv)
# Выход из программы
# Примечание: sys.exit(0) завершит выполнение программы, поэтому его обычно не используют в примерах.
# sys.exit(0)
# Версия Python
print("Версия Python:", sys.version)
# Путь поиска модулей
print("Путь поиска модулей:", sys.path)Модуль os предоставляет множество функций для взаимодействия с операционной системой.
Примеры:
import os
# Получить текущую рабочую директорию
current_dir = os.getcwd()
print("Текущая рабочая директория:", current_dir)
# Изменить текущую рабочую директорию
new_dir = '/tmp'
os.chdir(new_dir)
print("Рабочая директория изменена на:", os.getcwd())
# Список файлов и директорий в текущей директории
files = os.listdir('.')
print("Файлы и директории в текущей директории:", files)
# Создание новой директории
new_dir_name = 'new_dir'
if not os.path.exists(new_dir_name):
os.mkdir(new_dir_name)
print("Создана директория:", new_dir_name)
# Удаление файла
file_name = 'test.txt'
if os.path.exists(file_name):
os.remove(file_name)
print("Файл удален:", file_name)
else:
print("Файл не существует:", file_name)Модуль math предоставляет доступ к математическим функциям, определенным в стандарте C.
Примеры:
import math
# Вычислить квадратный корень
sqrt_value = math.sqrt(16)
print("Квадратный корень из 16:", sqrt_value)
# Вычислить синус угла в радианах
sin_value = math.sin(math.pi / 2)
print("Синус угла pi/2 радиан:", sin_value)
# Вычислить логарифм
log_value = math.log(10)
print("Натуральный логарифм 10:", log_value)
# Константы π и e
print("Константа π:", math.pi)
print("Константа e:", math.e)
# Округление вниз и вверх
floor_value = math.floor(3.7)
ceil_value = math.ceil(3.3)
print("Округление 3.7 вниз:", floor_value)
print("Округление 3.3 вверх:", ceil_value)Модуль random реализует генераторы псевдослучайных чисел для различных распределений.
Примеры:
import random
# Случайное число от 0 до 1
random_value = random.random()
print("Случайное число от 0 до 1:", random_value)
# Случайное целое число в диапазоне
random_int = random.randint(1, 10)
print("Случайное целое число от 1 до 10:", random_int)
# Случайный выбор из списка
choices = ['apple', 'banana', 'cherry']
random_choice = random.choice(choices)
print("Случайный выбор из списка:", random_choice)
# Перемешивание списка
my_list = [1, 2, 3, 4, 5]
random.shuffle(my_list)
print("Перемешанный список:", my_list)
# Случайное вещественное число в диапазоне
random_float = random.uniform(1.0, 10.0)
print("Случайное вещественное число от 1.0 до 10.0:", random_float)Модуль collections реализует специализированные контейнерные типы данных.
Примеры:
from collections import Counter, defaultdict, deque, namedtuple
# Counter
text = "abracadabra"
counter = Counter(text)
print("Подсчет символов в строке 'abracadabra':", counter)
# defaultdict
def_dict = defaultdict(int)
def_dict['apple'] += 1
print("defaultdict с начальным значением int:", def_dict)
# deque
queue = deque([1, 2, 3])
queue.appendleft(0)
queue.append(4)
print("Очередь deque после добавления элементов:", queue)
# namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
print("Координаты точки:", p.x, p.y)Модуль datetime предоставляет классы для работы с датой и временем.
Примеры:
from datetime import date, datetime, timedelta
# Текущая дата
today = date.today()
print("Текущая дата:", today)
# Текущее время
now = datetime.now()
print("Текущее время:", now)
# Вычисление разницы во времени
delta = timedelta(days=7)
next_week = today + delta
print("Дата через неделю:", next_week)
# Форматирование даты
formatted_date = now.strftime("%Y-%m-%d %H:%M:%S")
print("Форматированная дата и время:", formatted_date)
# Парсинг даты из строки
date_str = "2024-07-23"
parsed_date = datetime.strptime(date_str, "%Y-%m-%d")
print("Парсинг даты из строки:", parsed_date)Модуль itertools предоставляет функции для создания итераторов для эффективного цикла.
Примеры:
import itertools
# Бесконечный счетчик
print("Бесконечный счетчик с началом с 10 и шагом 2:")
for i in itertools.count(10, 2):
if i > 20:
break
print(i, end=' ')
print()
# Повторение элемента
counter = itertools.cycle(['A', 'B', 'C'])
print("Повторение элементов 'A', 'B', 'C':")
for _ in range(10):
print(next(counter), end=' ')
print()
# Комбинации
combinations = list(itertools.combinations('ABCD', 2))
print("Комбинации из 2 элементов строки 'ABCD':", combinations)
# Переключение значений
toggle = itertools.cycle([True, False])
print("Переключение значений True и False:")
for _ in range(6):
print(next(toggle), end=' ')
print()Комментарии и строковые литералы документации (docstrings) являются важными инструментами для написания чистого и понятного кода. Комментарии помогают другим разработчикам (и вам самим в будущем) понять, что делает конкретный фрагмент кода, а docstrings служат для создания документации, объясняющей, как пользоваться функциями, классами и модулями.
Комментарии в Python начинаются с символа # и продолжаются до конца строки. Python интерпретирует эти строки как
комментарии и игнорирует их при выполнении кода.
Пример использования комментариев:
# Это однострочный комментарий
x = 5 # Это комментарий после кода
# Следующий код вычисляет факториал числа
def factorial(n):
# Инициализируем результат
result = 1
# Перебираем все числа от 1 до n
for i in range(1, n + 1):
result *= i
return resultКомментарии помогают объяснить сложную логику, описать алгоритмы или просто напомнить о важных вещах.
В Python нет синтаксической поддержки многострочных комментариев, как в некоторых других языках программирования. Однако, для этого часто используют несколько однострочных комментариев:
Пример многострочных комментариев:
# Это многострочный комментарий.
# Он используется для объяснения большого блока кода
# или сложного алгоритма.
x = 10
y = 20
z = x + yDocstrings - это строки, используемые для документирования модулей, классов, методов и функций. В отличие от обычных
комментариев, docstrings можно получить программно через атрибут __doc__.
Пример использования docstring:
def add(a: int, b: int) -> int:
"""
Возвращает сумму двух чисел.
Аргументы:
a -- первое число
b -- второе число
Возвращает:
Сумма аргументов a и b.
"""
return a + b
# Получение docstring
print(add.__doc__)Этот docstring объясняет, что делает функция add, какие параметры она принимает и что возвращает.
Docstrings также используются для документирования классов и модулей.
Пример docstring для класса:
class Dog:
"""
Класс для представления собаки.
Атрибуты:
name (str) -- имя собаки
age (int) -- возраст собаки
Методы:
bark() -- заставляет собаку лаять
"""
def __init__(self, name: str, age: int):
"""
Инициализирует объект Dog с именем и возрастом.
Аргументы:
name (str) -- имя собаки
age (int) -- возраст собаки
"""
self.name = name
self.age = age
def bark(self) -> str:
"""Заставляет собаку лаять."""
return "Woof!"Пример docstring для модуля:
"""
Этот модуль предоставляет функции для работы с геометрическими фигурами.
Функции:
area_of_circle(radius) -- возвращает площадь круга с заданным радиусом
perimeter_of_square(side) -- возвращает периметр квадрата с заданной стороной
"""
def area_of_circle(radius: float) -> float:
"""Возвращает площадь круга с заданным радиусом."""
from math import pi
return pi * radius ** 2
def perimeter_of_square(side: float) -> float:
"""Возвращает периметр квадрата с заданной стороной."""
return 4 * sideСуществуют различные соглашения по форматированию docstring, включая стандарты Google, NumPy/SciPy и reStructuredText ( reST). Важно выбрать один стандарт и придерживаться его во всем проекте.
Пример docstring в стиле Google:
def multiply(a: int | float, b: int | float) -> int | float:
"""
Умножает два числа.
Args:
a (int, float): Первое число.
b (int, float): Второе число.
Returns:
int, float: Произведение аргументов a и b.
"""
return a * bDocstring как и типизации в современном мире считаются обязательным стандартом написания кода, и я ожидаю от вас использования их во всех домашках и модулях!
PEP8 (Python Enhancement Proposal 8) – это руководство по стилю написания кода на Python. Соблюдение этого стандарта помогает разработчикам создавать код, который легко читать и поддерживать. В этой лекции мы рассмотрим основные аспекты PEP8, включая правила именования переменных, использование пробелов, составные инструкции, тернарный оператор и отступы между функциями и классами.
-
Переменные и функции:
- Используйте стиль
snake_case(слова разделяются нижним подчеркиванием). - Примеры:
user_name = "John" calculate_total()
- Используйте стиль
-
Классы:
- Используйте стиль
CamelCase(каждое слово начинается с заглавной буквы). - Примеры:
class UserProfile: pass
- Используйте стиль
- Избегайте использования стиля
camelCaseдля функций и переменных. - Избегайте слишком коротких или слишком длинных имен.
- Избегайте имен, состоящих из одного символа (например,
x,y), если только это не циклические переменные или индексы.
- Добавляйте пробелы вокруг операторов присваивания (
=), арифметических операторов (+,-,*,/и т.д.), а также вокруг операторов сравнения (==,!=,<,>и т.д.).a = b + c if a == b: pass
- Не добавляйте пробелы внутри круглых, квадратных или фигурных скобок.
my_list = [1, 2, 3] function_call(a, b)
- Не добавляйте пробелы перед запятыми.
- Добавляйте пробелы после запятых.
my_tuple = (1, 2, 3)
Избегайте составных инструкций, когда несколько операторов записаны в одной строке.
import os;import sysimport os
import sysТернарный оператор в Python используется для написания кратких условий. Он позволяет сократить код, записывая условие и результат в одной строке.
result = x if condition else yis_even = True if number % 2 == 0 else FalseОтступы между функциями и классами способствуют лучшей читаемости кода и разделению логических блоков.
-
Отступы между методами внутри класса:
- Используйте один пустой ряд.
- Пример:
class MyClass: def method_one(self): pass def method_two(self): pass
-
Отступы между классами и функциями на верхнем уровне:
- Используйте два пустых ряда.
- Пример:
class FirstClass: pass class SecondClass: pass def my_function(): pass
В качестве домашки нужно ваш модуль разбить на небольшие логические куски.
Предполагаемая структура:
main.py - файл через который происходит запуск основной логики
files.py - файл куда надо переместить всю работу с файлами
utils.py - файл со всеми полезными функциями
