Как импортировать в основной файл модули нескольких побочных? Выдаёт ошибку
Всех приветствую! Подскажите, как правильно сделать: 1.Есть основной файл Main.py, в нём хранится меню бота с Reply клавиатурой и импортированы 3 нижеуказанных файла (для перевода в них с нажатия после выбора какого-то пункта в меню):
import Config import Cycle_a import Cycle_b bot = telebot.TeleBot(Config.Token_Bot)
2.Есть Config.py, в нём хранится сам Token_Bot. 3.Есть Cycle_а.py, в нём пошаговый бот с анкетой. Вызов токена бота осуществляется так и везде где:
from Main import bot
- Есть Cycle_b.py, в нём другой пошаговый бот. Вызов токена осуществляется аналогично вышеуказанному.
По отдельности файлы работают, при совмещении Main.py и Cycle_a.py все тоже нормально (с меню переводит на анкету). Но когда совмещаю все три файла выдаёт ошибку:
cannot import name ‘bot’ from partially initialized module ‘Main’ (most likely due to a circular import) (—путь—-\Main.py) File «—путь—\Cycle_a.py», line 8, in from Main import bot File «—путь—\Main.py», line 12, in import Cycle_a File «—путь—-\Cycle_b.py», line 9, in from Main import bot File «—путь—-\Main.py», line 11, in import Cycle_b
Как я понимаю, что у меня как-то не так реализован вызов бота с основного файла во все остальные и при запуске все вызывают одного бота. Совмещать все в один код не очень хотелось бы, желательно вообще вызов бота перенести в Config, но возникнет та же проблема.
Подскажите, как можно сделать по другому или исправить это же? Заранее благодарен.
P.S. Пишу на Python, библиотека TelegramBotApi
Дополняю кодом основными частями кода, где вызываю файлы:
import Config import Cycle_a import Cycle_b bot = telebot.TeleBot(Config.Token_Bot) def menu_step(message): markup = types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True) markup.add('Анкета 1', 'Анкета 2') markup.add('Обратная связь') bot.send_message(message.chat.id, 'Выбери ниже', reply_markup=markup) @bot.message_handler(content_types=['text']) def menu_two_step(message): if message.text.lower() == 'анкета 1': null_anketa_step(message) if message.text.lower() == 'анкета 2': null_anketass_step(message)
import telebot from telebot import types import sqlite3 import Main.py #from Main.py import bot #Пробовал так для обращения к боту. from Config import Group_id user_data = <> class User: def __init__(self, datas): self.datas = datas self.datass = '' conn = sqlite3.connect('DataBase.db', check_same_thread=False) cursor = conn.cursor() def db_table_val(user_id: int, dataone: str, datatwo: str): cursor.execute('INSERT INTO datatable (user_id, dataone, datatwo) VALUES (?, ?, ?)', (user_id, dataone, datatwo)) conn.commit() @bot.message_handler(commands=['anketaone']) def null_anketa_step(message): msg = bot.send_message(message.chat.id, "Введите данные №1") bot.register_next_step_handler(msg, process_one_step) def process_one_step(message): try: user_id = message.from_user.id user_data[user_id] = User(message.text) msg = bot.send_message(message.chat.id, 'Введите данные №2') bot.register_next_step_handler(msg, process_two_step) except Exception as e: bot.send_message(message.chat.id, 'Ошибка') def process_two_step(message): try: user_id = message.from_user.id user = user_data[user_id] user_data[user_id] = User(message.text) db_table_val(user_id=user_id, dataone=user.datas, datatwo=user.datass) bot.send_message(message.chat.id, 'Вы успешно ввели все данные') except Exception as e: bot.send_message(message.chat.id, 'Ошибка') bot.send_message(Group_id, 'У вас новая анкета!') bot.polling(none_stop=True)
В Cycle_b.py аналогично, просто вопросы другие и чуть больше.
- Добавил в конце каждого скрипта if name==’main‘: bot.polling(none_stop=True)
- Убрал в Cycle_a.py и Cycle_b.py: from Main import bot
- Соответственно в каждом файле добавил токен бота: bot = telebot.TeleBot(Config.Token_Bot)
Теперь все запускается без ошибки, при нажатии Анкета 1 -> запускается скрипт из побочного файла -> Выдаёт «Введите данные №1, но на следующий шаг не переводит. Ошибок никаких нет, можно даже опять вызвать меню. Просто не хочет переводить на следующий шаг.
Файл пакета __init__.py
Если файл с именем __init__.py присутствует в каталоге пакета, то он вызывается при импорте пакета или модуля в пакете. Это может быть использовано для выполнения кода инициализации пакета, например инициализации данных уровня пакета.
Поместим следующий код в файл __init__.py :
print(f'Файл __init__.py в пакете __name__>') var_init = ['one', 'two', 'three']
Добавим файл __init__.py в каталог pkg из примера «Пакеты модулей в Python»:
-- pkg | |---- __init__.py | |---- mod1.py | |---- mod2.py
Теперь при импорте пакета инициализируется глобальная переменная var_init :
>>> import pkg # Файл __init__.py в пакете pkg >>> pkg.var_init # ['one', 'two', 'three']
Модуль в пакете может получить доступ к глобальным переменным пакета файла __init__.py , импортируя его в свою очередь. Изменим файл модуля пакета mod1.py следующим образом:
def foo(): from pkg import var_init print('Модуль 1, функция foo(), var_init =', var_init)
>>> from pkg import mod1 # Вызов __init__.py в пакете pkg >>> mod1.foo() # Модуль 1, функция foo(), var_init = ['one', 'two', 'three']
Файл __init__.py может также использоваться для автоматического импорта модулей пакета. В материале «Пакеты модулей в Python» говорилось, что оператор import pkg помещает только имя пакета pkg в область видимости вызывающего объекта и не импортирует никакие модули. Изменим файл пакета __init__.py в каталоге pkg , дописав строку импорта модулей import pkg.mod1, pkg.mod2 .
print(f'Файл __init__.py в пакете __name__>') x = ['one', 'two', 'three'] import pkg.mod1, pkg.mod2
Теперь при импорте пакета pkg , модули в mod1 и mod2 импортируются автоматически:
>>> import pkg # Файл __init__.py в пакете pkg >>> pkg.mod1.foo() # Модуль 1, функция foo(), var_init = ['one', 'two', 'three'] >>> pkg.mod2.bar() # Модуль 2, функция bar()
Примечание: большая часть статей про пакеты в Python утверждает, что файл __init__.py должен присутствовать в каталоге пакета при его создании. До версии Python 3.3 это было правдой. Само присутствие файла __init__.py означало для Python, что пакет был определен. Файл мог содержать код инициализации или даже быть пустым, но он должен был присутствовать.
Начиная с Python 3.3, были введены неявные пространств имен пакета, что позволяют создать пакет без каких-либо __init__.py файлов. Конечно, файл __init__.py все еще может присутствовать, если требуется инициализация пакета.
- ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
- Спецификация инструкции import
- Определение модуля и его импорт
- Конструкция импорта import modulle as name
- Конструкция импорта from modulle import names
- Конструкция импорта from modulle import name as alt_name
- Как Python ищет импортируемый модуль
- Список имен, определенных в модуле Python
- Выполнение модуля как скрипта
- Перезагрузка модуля
- Пакеты модулей
- Файл пакета __init__.py
- Переменная __all__ в пакетах и модулях
- Переменная пакета __path__
- Относительный импорт пакетов
- Вложенные подпакеты
- Пространства имен пакета
- Настройка доступа к атрибутам модуля
Модуль импорта в Python с примерами
Модуль — это файл с кодом Python. Код может быть в форме переменных, функций или определенных классов. Имя файла становится именем модуля.
Например, если имя вашего файла — guru99.py, имя модуля будет guru99. Благодаря функциональности модуля вы можете разбить свой код на разные файлы вместо того, чтобы писать все в одном файле.
Что такое модуль импорта Python?
Файл рассматривается как модуль в Python. Чтобы использовать модуль, вам необходимо импортировать его, используя импорт ключевое слово. Функция или переменные, присутствующие внутри файла, могут быть использованы в другом файле путем импорта модуля. Эта функциональность доступна на других языках, таких как машинописный текст, JavaScript, Java, Ruby и т. д.
Как создать и импортировать модуль в Python?
Теперь мы создадим модуль и импортируем его в другой файл.
Вот процесс создания и импорта модуля, как показано на снимке экрана:
Следуйте инструкциям, чтобы создать модуль в Python.
Структура папок, используемая для тестирования кода, следующая:
modtest/ test.py display.py
Шаг 1) Создайте файл и назовите его test.py.
Шаг 2) Внутри test.py создайте функцию display_message().
Def display_message(): return "Welcome to Guru99 Tutorials!"
Шаг 3) Теперь создайте еще один файл display.py.
Шаг 4) Внутри display.py импортируйте файл Moduletest.py, как показано ниже:
import test
При импорте вам не обязательно указывать test.py, а только имя файла.
Шаг 5) Затем вы можете вызвать функцию display_message() из test.py внутри display.py, вам нужно использовать имя_модуля.имя_функции.
Import test print(test.display_message())
Шаг 6) Когда вы выполните display.py, вы получите следующее Вывод:
Welcome to Guru99 Tutorials!
Импорт класса в Python
Ранее мы видели простой модуль с функцией. Здесь будет создан класс и ссылка на класс внутри другого файла.
Структура папок для тестирования кода следующая:
myproj/ Car.py display.py
Создайте файл Car.py со следующим кодом:
Имя файла: Car.py
class Car: brand_name = "BMW" model = "Z4" manu_year = "2020" def __init__(self, brand_name, model, manu_year): self.brand_name = brand_name self.model = model self.manu_year = manu_year def car_details(self): print("Car brand is ", self.brand_name) print("Car model is ", self.model) print("Car manufacture year is ", self.manu_year) def get_Car_brand(self): print("Car brand is ", self.brand_name) def get_Car_model(self): print("Car model is ", self.model)
В файле Car.py есть атрибуты name_name, model и manu_year. Внутри класса определены функции car_details(), get_Car_brand(), get_Car_model().
Давайте теперь используем файл Car.py в качестве модуля в другом файле с именем display.py.
Имя файла: display.py
import Car car_det = Car.Car("BMW","Z5", 2020) print(car_det.brand_name) print(car_det.car_details()) print(car_det.get_Car_brand()) print(car_det.get_Car_model())
Вывод:
BMW Car brand is BMW Car model is Z5 Car manufacture year is 2020 Car brand is BMW Car model is Z5
Таким образом, мы можем получить доступ ко всем переменным и функциям из Car.py с помощью модуля Car.
Использование модуля from для импорта
Вместо импорта всего кода вы можете импортировать только небольшую часть модуля, т. е. только необходимые функции и имена переменных из модуля.
Если вы хотите импортировать только определенные элементы, вы можете использовать ключевое слово «from», чтобы импортировать то, что вы хотите.
from module import your function_name , variables. etc.
Структура папок, используемая для тестирования кода, следующая:
modtest/ test.py display.py
В test.py есть две функции, как показано:
Имя файла: test.py
defdisplay_message(): return "Welcome to Guru99 Tutorials!" def display_message1(): return "All about Python!"
Теперь вам нужна функция display_message(). К импортируемой функции или переменной можно получить прямой доступ, как показано ниже:
Имя файла: display.py
from test import display_message print(display_message())
Вывод:
Welcome to Guru99 Tutorials!
Теперь, если вы воспользуетесь функцией display_message1() , она выдаст ошибку, что функция не определена, как показано ниже:
from test import display_message print(display_message1())
Вывод:
Traceback (most recent call last): File "display.py", line 3, in print(display_message1()) Name Error: name 'display_message1' is not defined
Импорт всего из модуля
Импорт позволяет импортировать весь модуль, используя команду import, за которой следует имя модуля, т. е. имя файла или используемой библиотеки.
Import module
from module import *
Структура папок, используемая для тестирования кода, следующая:
modtest/ test.py display.py
Ниже приведены детали кода внутри test.py.
my_name = "Guru99" my_address = "Mumbai" defdisplay_message(): return "Welcome to Guru99 Tutorials!" def display_message1(): return "All about Python!"
Использование модуля импорта
Используя только имя модуля импорта, для ссылки на переменные и функции внутри модуля необходимо добавить префикс имени модуля.
Имя файла: display.py
Import test print(test.display_message()) print(test.display_message1()) print(test.my_name) print(test.my_address)
Тест имени модуля используется для ссылки на функцию и переменные внутри теста модуля.
Вывод:
Welcome to Guru99 Tutorials! All about Python! Guru99 Mumbai
Использование импорта *
Давайте посмотрим пример использования Импортировать *, С помощью Импортировать *, функции и переменные доступны напрямую, как показано в примере ниже:
from test import * print(display_message()) print(display_message1()) print(my_name) print(my_address)
Вывод:
Welcome to Guru99 Tutorials! All about Python! Guru99 Mumbai
Функция реж( )
dir() — это встроенная функция Python. Функция dir() возвращает все свойства и методы, включая встроенные свойства данного объекта.
Поэтому, когда dir() используется в модуле, он предоставит вам переменные и функции, которые присутствуют внутри модуля.
Вот рабочий пример dir() в модуле. У нас есть класс Car.py, давайте импортируем Car и назначим его dir(), чтобы увидеть результат.
Структура папок для тестирования кода будет следующей:
test prop/ Car.py test.py
Имя файла: Car.py
class Car: brand_name = "BMW" model = "Z4" manu_year = "2020" def __init__(self, brand_name, model, manu_year): self.brand_name = brand_name self.model = model self.manu_year = manu_year def car_details(self): print("Car brand is ", self.brand_name) print("Car model is ", self.model) print("Car manufacture year is ", self.manu_year) def get_Car_brand(self): print("Car brand is ", self.brand_name) def get_Car_model(self): print("Car model is ", self.model)
Имя файла: test.py
import Car class_contents = dir(Car) print(class_contents)
Вывод дает нам имя класса и всех функций, определенных в Car.py.
Вы также можете попробовать использовать dir() во встроенном модуле, доступном в Python. Давайте попробуем то же самое JSON модуль, как показано в примере ниже. Он отобразит все свойства и методы, доступные в JSON модуль.
Import json json_details = dir(json) print(json_details)
Вывод:
['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', '__all__', '__author__', '__bu iltins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__pac kage__', '__path__', '__spec__', '__version__', '_default_decoder', '_default_en coder', 'codecs', 'decoder', 'detect_encoding', 'dump', 'dumps', 'encoder', 'loa d', 'loads', 'scanner']
Packages
Пакет — это каталог, в котором определены все модули. Чтобы интерпретатор Python воспринимал его как пакет, в вашем каталоге должен быть файл init.py. init.py создает каталог как пакет. Вот макет пакета, над которым мы будем работать.
Название пакета мой пакет. Чтобы начать работу с пакетом, создайте каталог с именем package/. Внутри каталога создайте пустой файл с именем __init__.py. Создайте еще 3 файла Module1.py, Module2.py и Module3.py и определите функции, как показано на снимке экрана. Вот подробности о модуле1.py,модуле2.py и модуле3.py.
модуль1.py
def mod1_func1(): print("Welcome to Module1 function1") def mod1_func2(): print("Welcome to Module1 function2") def mod1_func3(): print("Welcome to Module1 function3")
модуль2.py
def mod2_func1(): print("Welcome to Module2 function1") def mod2_func2(): print("Welcome to Module2 function2") def mod2_func3(): print("Welcome to Module2 function3")
модуль3.py
def mod3_func1(): print("Welcome to Module3 function1") def mod3_func2(): print("Welcome to Module3 function2") def mod3_func3(): print("Welcome to Module3 function3")
Так, пакетон готов к использованию. Теперь вызовите пакет внутри любого файла, как показано ниже: test.py:
Здесь mypackage.module1 импортируется и получает псевдоним как мод1. Аналогично вы можете использовать другие модули mod2.py и modul3.py из моего пакета.
import mypackage.module1 as mod1 print(mod1.mod1_func1()) print(mod1.mod1_func2()) print(mod1.mod1_func2())
Вывод:
Welcome to Module1 function1 None Welcome to Module1 function2 None Welcome to Module1 function2 None
Мы только что продемонстрировали пакет с простым модулем с функциями внутри него. В соответствии с вашим проектом вы также можете упаковать подпакеты. Подпапки/содержащие модули с определенными классами.
Путь поиска модуля Python
Во время выполнения, когда попадается Python имя модуля импорта, интерпретатор пытается найти модуль. Он ищет модуль в списке встроенных модулей. Позже каталоги определяются внутри sys.path.
Подводя итог, интерпретатор выполняет следующий поиск, чтобы найти модуль:
- В вашем текущем каталоге.
- В списке встроенных модулей
- Внутри каталогов sys.path
Вы можете получить подробную информацию о sys.path, импортировав модуль sys и распечатав sys.path. Он предоставит вам список каталогов, как показано ниже:
importsys print(sys.path)
Вывод:
['Python Latest\\task2', 'Users\\AppData\\Local\\Programs\\Python\ \Python37\\python37.zip', 'Users\\AppData\\Local\\Programs\\Python\\P ython37\\DLLs']
Вы также можете изменить путь и сохранить каталоги в соответствии с вашими требованиями.
Использование псевдонима модуля при импорте
Вы также можете преобразовать имя модуля в более короткую форму, присвоив ему псевдоним. Псевдоним можно создать с помощью ключевого слова.
import filename as alias name
Структура папок для тестирования кода будет следующей:
Mod test/ test.py display.py
Ниже приведен код внутри test.py.
my_name = "Guru99" my_address = "Mumbai" def display_message(): return "Welcome to Guru99 Tutorials!" def display_message1(): return "All about Python!"
Теперь мы будем использовать псевдоним для test.py в display.py.
Import test as t print(t.display_message()) print(t.display_message1()) print(t.my_name) print(t.my_address)
Псевдоним, используемый для тестового модуля, — t. Таким образом, на функцию и переменные из test.py можно ссылаться, используя псевдоним t.
Вывод:
Welcome to Guru99 Tutorials! All about Python! Guru99 Mumbai
Абсолютный и относительный импорт в Python
Теперь вы знаете, как импортировать файл как модуль внутри другого файла. Давайте теперь посмотрим, как управлять файлами, доступными в папках. Файлы в папках можно импортировать с помощью абсолютного или относительного импорта.
Предположим, у вас есть структура папок проекта, как показано ниже:
Корневая папка — мой проект/. Он имеет две подпапки package1 и package2.
Папка package1 содержит два модуля: Module1.py и Module2.py.
В папке package2 есть один класс myclass.py, подпакет subpkg с модулем3.py и последний модуль4.py.
- В файле mod1.py есть функция myfunc1.
- В файле mod2.py есть функция myfunc2.
- В mod3.py есть функция myfunc3.
- В файле mod4.py есть функция myfunc4.
Использование абсолютного импорта
Для абсолютного импорта вам необходимо добавить полный путь к вашему модулю прямо из корневой папки проекта.
Давайте теперь посмотрим, как использовать абсолютный импорт для ссылки на функции, присутствующие в каждом модуле.
Для работы с функциейmyfunc1 вам потребуется импортировать следующим образом:
from package1.module1 import myfunc1 or from package1 import module1 module1.myfunc1()
Для работы с функцией myfunc3 вам потребуется импортировать следующим образом:
from package1.subpkg.module3 import myfunc3 or from package1.subpkg import module3 module3.myfunc3()
Преимущества и недостатки использования абсолютного импорта
Вот преимущества использования абсолютного импорта:
- Становится легко отслеживать модули для проверки кода.
- Простой в использовании и очень простой.
- Если проект будет перемещен по другому пути, импорт останется прежним.
Недостатки использования абсолютного импорта
Вот недостатки использования абсолютного импорта:
- Путь импорта может оказаться очень длинным, если модули вложены или имя модулей длинное.
Использование относительного импорта
Учитывая ту же структуру папок, упомянутую ниже, мы увидим, как импортировать ее, используя относительный импорт.
При относительном импорте импортируемый модуль относится к текущему местоположению, то есть месту, где присутствует оператор импорта.
Синтаксис
При относительном импорте вам необходимо добавить точку (.) перед именем модуля при импорте с использованием от.
Перед именем модуля будут стоять 2 точки (..), если модуль находится на уровень выше текущего местоположения.
Ссылаясь на упомянутый выше рисунок структуры папок, мы видим следующие модули с их функциями, на которые нам нужно обратиться.
- В файле mod1.py есть функция myfunc1.
- В файле mod2.py есть функция myfunc2.
- В mod3.py есть функция myfunc3.
- В файле mod4.py есть функция myfunc4.
Для работы с функциейmyfunc1 вам потребуется импортировать следующим образом:
from .module1 import myfunc1
Для работы с функцией myfunc3 вам потребуется импортировать следующим образом:
from .subpkg.module3 import myfunc3
Преимущества относительного импорта
- С относительным импортом легко работать.
- Из текущего местоположения импорт может быть сокращен по сравнению с абсолютным импортом.
Недостатки относительного импорта
- Используя относительный импорт, трудно отследить, где находится код.
Итоги
- Импорт в Python помогает обращаться к коду, т. е. к функциям/объектам, записанным в другом файле. Он также используется для импорта библиотек/пакетов Python, которые установлены с помощью pip (менеджер пакетов Python), а затем вам необходимо использовать их в своем коде.
- Функциональность импорта доступна на других языках, таких как машинописный текст, JavaScript, Java, Ruby и т. д.
- Модуль Python — это код, написанный внутри файла, например (test.py). Внутри вашего файла вы можете определить переменные, функции или класс. Весь файл становится модулем и может быть импортирован в другой файл для ссылки на код.
- Благодаря функциональности модуля вы можете разбить свой код на разные файлы вместо того, чтобы писать все в одном файле. Позже, используя импорт, вы сможете обратиться к коду внутри нужного вам файла.
- Python имеет встроенные модули, а также внешние библиотеки/пакеты, установленные с помощью менеджер пакетов питона (pip), например pandas, NumPy и т. д., называются модулями.
- Вместо импорта всего кода вы можете импортировать только небольшую часть модуля, т. е. только необходимые функции и имена переменных из модуля.
- Вы также можете преобразовать имя модуля в более короткую форму, присвоив ему псевдоним. Псевдоним можно создать с помощью ключевого слова.
- Пакет — это каталог, в котором определены все модули. Чтобы интерпретатор Python воспринимал его как пакет, в вашем каталоге должен быть файл __init.py. init.py создает каталог как пакет. Вот макет пакета, над которым мы будем работать.
- Во время выполнения, когда попадается Python имя модуля импорта, интерпретатор пытается найти модуль. Он ищет модуль в списке встроенных модулей. Позже каталоги определяются внутри sys.path.
- Для абсолютного импорта вам необходимо добавить полный путь к вашему модулю прямо из корневой папки проекта.
- При относительном импорте импортируемый модуль относится к текущему местоположению, то есть месту, где присутствует оператор импорта.
- Онлайн-компилятор Python (редактор/интерпретатор/IDE) для запуска кода
- Учебное пособие по PyUnit: Платформа модульного тестирования Python (с примером)
- Как установить Python в Windows [Pycharm IDE]
- Hello World: создайте свою первую программу на Python
- Переменные Python: как определить/объявить типы строковых переменных
Import Python
Основы
Автор Иван Душенко На чтение 12 мин Просмотров 15.9к. Опубликовано 07.02.2022
В своей работе программист обязан «разделять сущности» когда в коде нарастает сложность. Чаще всего это означает, что какой-то блок кода разбивают на более мелкие блоки, таки как функции, классы, методы класса… Но что делать, если самих этих блоков кода уже так много, что само их количество создаёт сложность? Приходится «повышать уровень абстракции» — разделять код на несколько файлов. В этом уроке мы научимся использовать несколько таких файлов как целостный код. Одной из важных характеристик языка программирования является то, как в нём устроен этот механизм. Что ж, Python как обычно предоставляет удобный механизм, представляющий собой систему импортов файлов.
Давайте договоримся о терминах: любой файл с кодом на Питоне может использоваться в другом файле Питона и называется в таком случае модулем или библиотекой. Кстати, Python так же может использовать файлы на C или C++.
Подключение модуля из стандартной библиотеки
Стандартная библиотека – это набор наиболее распространённых и используемых модулей, которые поставляются вместе с языком Пайтон. Другими словами, когда Вы устанавливаете язык на свой компьютер, этот набор идёт в комплекте.
Для того, чтоб получить доступ к какому-то модулю из стандартной библиотеки достаточно написать в коде ключевое слово import Python, вот так:
import sysЭта строка импортирует из стандартной библиотеки модуль sys.
print(sys) print(type(sys)) # Вывод:
На самом деле, при импорте c Python import создаётся переменная sys, которая хранит ссылку на файл:
import sys print('sys', sys) print('type(sys)', type(sys)) os = sys sys = 1 print('sys', sys) print('type(sys)', type(sys)) print('os', os) print('type(os)', type(os)) # Вывод: sys type(sys) sys 1 type(sys) os type(os)Модуль sys помогает взаимодействовать с системой Вашего компьютера. Теперь можно использовать объекты и функции из этой библиотеки в своём коде. Делается это при помощи синтаксиса: «модуль.атрибут». К примеру, узнать, какой тип операционной системы используется:
import sys print(sys.platform) # Вывод: win32После ключевого слова import можно указать не одну, а несколько Python modules (библиотек). Однако, так делать не стоит, поскольку от этого ухудшается читаемость кода:
import sys, pprint pprint.pprint(sys.platform) # Вывод: 'win32'Важно знать, что при import module код из модуля сразу же исполняется. К примеру, если импортировать следующий код:
def foo(): print("foo") print("bar")то в терминале появится:
Надпись foo не появилась, так как функция пока нигде не вызывалась. Если сделать так:
def foo(): print("foo") print("bar") foo()то в терминал будет выведено:
bar fooТо, что код начинает выполняться сразу, сделано для того, чтоб можно было произвести инициализацию модуля, то есть подготовить его каким-то образом перед использованием. К примеру, запустить сервер или заполнить переменные значениями. Если у Вас есть код, который должен выполняться, когда Вы запускаете скрипт, но не должен, когда Вы импортируете этот скрипт, используйте стандартный приём:
def foo(): print("foo") if __name__ == '__main__': print("bar") foo()Теперь код будет исполняться так, как описано выше.
Ошибки
Если попытаться использовать что-то, чего нет в модуле, интерпретатор вернёт исключение AttributeError:
import sys print(sys.wrong_argument) # Вывод: Traceback (most recent call last): File "C:\Users\ivand\AppData\Roaming\JetBrains\PyCharm2021.2\scratches\scratch.py", line 4, in print(sys.wrong_argument) AttributeError: module 'sys' has no attribute 'wrong_argument' Process finished with exit code 1Если попытаться импортировать не существующий модуль, Вы увидите исключение ModuleNotFoundError:
import wrong_module # Вывод: Traceback (most recent call last): File "C:\Users\ivand\AppData\Roaming\JetBrains\PyCharm2021.2\scratches\scratch.py", line 1, in import wrong_module ModuleNotFoundError: No module named 'wrong_module' Process finished with exit code 1Использование псевдонимов
Распространённой практикой является использование коротких псевдонимов для длинных названий импортируемого модуля. Для этого существует специальное слово as.
import itertools as iter print(iter) # Вывод:
На самом деле as – лишь «синтаксический сахар», ведь происходит здесь то же самое, что мы проделали чуть раньше: замена переменной, хранящей ссылку на модуль.
import itertools as iter import itertools it = itertools print(it is iter) # Вывод: TrueИнструкция from
Зачастую не требуется весь модуль, а лишь какая-то его часть. Вы ведь не покупаете чайную лавку целиком, когда вам нужна одна упаковка чая?
В Python есть ключевое слово from, которое позволяет импортировать только нужные части. Простейший случай использования выглядит так:
from sys import *Это импортирует все сущности из модуля и теперь к ним можно обращаться так, будто они объявлены в текущем файле:
from sys import * print(platform) # Вывод: win32Но такой вариант является максимально плохим! Почему? Всё дело в пространстве имён. Если пользоваться этим способом, пространство имён выходит из-под Вашего контроля – теперь Вы не знаете какие имена переменных, функций, классов используются в Вашей программе, из-за чего могут возникнуть неприятности. В конце концов, Вы же не собираетесь, не глядя купить всё, что есть в чайной лавке?
Для того, чтоб импортировать только определённые сущности, укажите их имена после ключевого слова import (можно несколько).
from sys import platform print(platform) # Вывод: win32И здесь тоже можно использовать псевдонимы.
from sys import platform as pl print(pl) # Вывод: win32Создание своего модуля на Python
Как уже говорилось выше, любой код на Python является модулем, так что создавать модули очень просто. К примеру, создадим файл hello.py:
def say(): print("Hello!")Теперь в той же директории создадим файл talk.py, в который будем импортировать функцию say:
from hello import say say() # Вывод: Hello!Да, всё так просто!
А как установить модуль, написанный кем-то другим? Используйте pip instal.
Именование модулей
Здесь есть ограничения. Самое важное – нельзя именовать модуль ключевым словом самого Пайтона (к примеру, pass или for), иначе его просто не получится импортировать. Так же не стоит использовать идентификаторы Питона (к примеру, class или type). Получить полный список зарезервированных слов и идентификаторов можно при помощи следующего кода:
print(help("keywords")) # Вывод: Here is a list of the Python keywords. Enter any keyword to get more help. False break for not None class from or True continue global pass __peg_parser__ def if raise and del import return as elif in try assert else is while async except lambda with await finally nonlocal yield NoneКроме того, не желательно давать модулю такое же имя, как у модулей встроенной библиотеки, либо какого-либо из распространённых сторонних модулей – это вносит не нужную неоднозначность.
Куда поместить модуль?
Туда, где его потом можно будет найти. Пути поиска модулей указаны в переменной sys.path. В него включены текущая директория (то есть модуль можно оставить в папке с основной программой), а также директории, в которых установлен python. Кроме того, переменную sys.path можно изменять вручную, что позволяет положить модуль в любое удобное для вас место (главное, не забыть в главной программе модифицировать sys.path).
Пакеты
Что же делать, если Ваш проект разрастается и модулей уже очень много? Пайтон предлагает элегантное решение: почему бы не использовать уже существующую в операционной системе иерархию – директории (папки)? В Питоне это называется пакеты.
Пакет в Python — директория с обязательным модулем __init__.py. Остальное содержимое может включать в себя и модули, и другие пакеты.
__init__.py – файл, который выполняется сразу после импорта пакета и предназначен для инициализации – предварительной подготовки перед использованием содержимого пакета. Этот механизм аналогичен тому, как выполняется основной поток кода при импорте модуля.
Если пакет не содержит __init__.py, то он превращается в так называемое «пространство имён» — может содержать другие пакеты, но не может содержать модули на первом уровне.