- Импорт модулей в Python
- Классы и функции импорта из модуля
- Пользовательский модуль импорта
- Импорт as
- Импорт из другого каталога
- Класс импорта из другого файла
- Заключение
- Python import, как и для чего?
- Как использовать import?
- Что можно импортировать?
- В чем же подвох?
- Ветвистая структура приложения и существующие подходы импортирования
- P.S.
Импорт модулей в Python
Оператор импорта в Python используется для импорта модулей, которые мы хотим использовать в нашей программе. Модули – это скрипты в Python, содержащие служебные функции, типы, классы и т.д. Есть много модулей, которые мы регулярно используем в программах, такие как sys, os, collections и т.д.
Если мы хотим импортировать встроенные модули в Python или любой сторонний модуль, установленный с помощью диспетчера пакетов, такого как PIP, мы можем очень легко импортировать и использовать их в нашей программе.
import collections import sys
Python ищет модули и пакеты в свойстве sys.path. Этот путь всегда содержит текущий каталог, из которого выполняется сценарий, поэтому любой модуль в текущем каталоге можно импортировать как есть.
Импорт в Python чувствителен к регистру, поэтому import sys и import Sys ищут разные модули для импорта.
Python сначала ищет модуль во встроенных модулях. Если не найден, то ищет модули в текущем каталоге. Итак, если у нас есть файл math.py в том же каталоге, что и наш основной скрипт, он будет загружен при вызове import math, если модуль ‘math’ отсутствует во встроенных модулях. Вы можете получить список встроенных модулей, используя sys.builtin_module_names. На изображении ниже показаны встроенные модули:
Классы и функции импорта из модуля
Мы также можем импортировать определенные классы из модуля. Таким образом, мы можем импортировать определенные части модуля и использовать их. Это также помогает в написании свободного кода. Мы можем добиться этого, используя ключевое слово from с оператором импорта.
from collections import namedtuple from os import path
Пользовательский модуль импорта
Когда мы создаем скрипт, мы можем импортировать его в другой скрипт Python, используя его имя. Допустим, у нас есть следующая структура каталогов с несколькими скриптами.
У нас есть следующие функции, определенные в файле utils.py.
def add(i, j): return int(i) + int(j) def uppercase(s): return str(s).upper()
Мы можем импортировать его в python_import_examples.py и использовать его функции.
import utils print(utils.add(10,10)) print(utils.uppercase('java'))
Импорт as
Мы можем определить собственное имя для импортированного модуля, используя оператор import as.
# python import as import utils as u print(u.add(10,10)) print(u.uppercase('java'))
Результат будет таким же, как и в предыдущей программе.
Импорт из другого каталога
Если скрипт, который мы импортируем, находится в том же каталоге, то мы можем импортировать его так же, как и встроенные модули. Однако, если скрипт присутствует в другом каталоге, мы можем использовать библиотеку importlib, чтобы импортировать их как модуль.
Скажем, наш Strutils.py имеет следующие функции:
def uppercase(s): return str(s).upper() def lowercase(s): return str(s).lower()
Теперь давайте посмотрим, как использовать importlib для импорта этого скрипта в наш пример.
# Refer: https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly # Refer: https://stackoverflow.com/questions/4383571/importing-files-from-different-folder import importlib, importlib.util def module_from_file(module_name, file_path): spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module strutils = module_from_file("strutils", "../mymodule/strutils.py") print(strutils.uppercase('java')) print(strutils.lowercase('DATA'))
Класс импорта из другого файла
Мы можем импортировать скрипты и использовать определенные в них классы с помощью importlib. Допустим, у нас есть классы Person и Student, определенные в файле myclasses.py.
class Person: name = "" def __init__(self, personName): self.name = personName def showName(self): print(self.name) class Student(Person): id = 0 def __init__(self, studentName, studentId): Person.__init__(self, studentName) self.id = studentId def getId(self): return self.id
Вот пример кода, в котором я использую ранее определенную функцию для импорта этого скрипта и использования его классов.
#python import class from another file mc = module_from_file("myclasses", "../mymodule/myclasses.py") p = mc.Person('Pankaj') p.showName() s = mc.Student('David',25) s.showName() print(s.getId())
Обратите внимание, что мы можем сохранить любое имя для импортируемого модуля, это похоже на использование оператора import as.
Есть еще один способ импортировать скрипты из другого каталога с помощью модуля sys.
import sys sys.path.append("../mymodule/") from myclasses import Person as PC p = PC('Meghna') p.showName()
Это полезно, когда мы хотим импортировать только определенные классы и функции из импортированного файла. Кроме того, использование этого кода намного проще для понимания.
Заключение
Оператор импорта Python позволяет нам импортировать модули, определенные классы и функции из модулей. Его очень легко использовать, и, поскольку в большинстве случаев мы работаем со встроенными модулями или модулями, установленными с использованием PIP, нам не нужно писать логику для загрузки скриптов из другого каталога.
Python import, как и для чего?
В языке программирования Python подключение пакетов и модулей осуществляется с помощью import. Это позволяет распределять код по логическим «узлам» приложения(модели данных, обработчики, и тп.), что позволяет получить менее нагруженные кодом файлы.
- Повышается читаемость кода.
- Код логически разбит по «узлам», его поиск и дальнейший отлов ошибок становится понятнее и проще.
- Для разработки в команде это дает более четкое понимание, что и где делает каждый при выполнении «задания».
Как использовать import?
Синтаксис import в Python достаточно прост и интуитивно понятен:
# В данной строке импортируется something_we_want import something_we_want # В данной строке импортируется something_we_want, как aww(логично и просто) import something_we_want as aww # В данной строке импортируется из something_we_want something(логично и просто) from something_we_want import something # В данной строке импортируется из something_we_want something, как s(логично и просто) from something_we_want import something as s # Синтаксис as позволяет обращаться к импортируемому по новому нами описанному # далее имени(это работает только в рамках нашего файла)
Что можно импортировать?
Для более глубокого понимания import стоит рассмотреть пример, представленный ниже.
def something(): pass somedata = 5
# 1 случай import something_we_want something_we_want.something() import something_we_want print(something_we_want.somedata) # 2 случай import something_we_want as aww aww.something() import something_we_want as aww print(aww.somedata) # 3 случай from something_we_want import something something() from something_we_want import somedata print(somedata) # 4 случай from something_we_want import something as s s() from something_we_want import somedata as sd print(sd) # Классы импортируются по аналогии с функциями
Красиво, читаемо и понятно.
В чем же подвох?
Но даже в таком простом примере есть подвох, о котором многие не догадываются(если вы начинающий программист, то лучше перейдите к следующему оглавлению).
Идеология Python достаточно интересна, что позволяет ему иметь низкий порог вхождения, низкое время написания кода, высокую читаемость, но именно в ней и кроется подвох.
По своему опыту использования данного языка, сложилось отчетливое ощущение главной идеи ООП(все есть объект). Что же в этом плохого?
Все файлы, функции и тд. это объект. Но что это за объект и класс стоят за файлами(модулями)?
Все просто, это любимый всеми программистами класс, использующий паттерн проектирования Singleton.
Поэтому при достаточно ветвистой структуре, импорт переменной и дальнейшая ее модификация может порождать достаточно не простые в понимании баги(переменная в своем цикле жизни может иметь любое значение и никаких гарантий нет).
Ветвистая структура приложения и существующие подходы импортирования
Часто в разработке приложений программисты пытаются разбить программу по логическим «узлам». Данный подход повышает читаемость и позволяет вести разработку в команде(один человек занимается реализацией одного «узла», второй другого). Так порождается структура приложения, которая зачастую виду сложности функционала является достаточно обширной(ветвистой, потому что имея одну точку входа откуда уже обрастая функционалом это становится похожим на дерево).
Пример ветвистой структуры:
Существует 2 подхода импортирования(лучше выбрать один и придерживаться его весь проект):
Пример именованного импорта из models.py в auth.py:
# auth.py from app.models import User
Пример неименованного импорта из models.py в auth.py:
# auth.py from ..models import User # Количество точек указывает на сколько (обьектов) мы поднимаемся от исходного. # В данном примере первая точка поднимает нас на уровень обьекта handlers, # А вторая точка поднимает нас на уровень обьекта app
Это два абсолютно разных подхода. В первом случае мы «идем» из «корня»(входной точки нашего приложения). Во втором случае мы «идем» от «листа»(нашего файла).
Плюсы и минусы подходов импорта:
Видна структура импорта и приложения.
Видна часть структуры импорта.
Программисту не нужно знать полную структуру приложения.
Импорт не зависит от точки входа.
Код становится не привязанным к приложению. Что по сути позволяет исполнить код из любой точки(тесты, отдельно и тд.). Повышается отлаживаемость. Появляется возможность разработки отдельных узлов приложения без полного вовлечения программиста в проект.
Импорт зависит от точки входа.
Программисту необходимо знать структуру приложения. Код сильно связан с приложением. Что по сути усложняет отладку, тестирование, и тд. Программист становится сильно вовлеченным в проект.
Снижается читаемость импорта.
Хоть первый подход и имеет существенные минусы в использовании, но тем не менее он популярен. Программистам он привычнее, хоть и имеет недостатки. А начинающие часто не задумываются об альтернативах.
P.S.
Данная статья была написана для начинающих программистов, которые хотят научиться писать на языке программирования Python, поэтому часть примеров заведомо упрощена и нацелена на освещение существующих подходов.
Пишите тот код, который бы сами хотели получить от исполнителя.