Как импортировать класс из другого файла python

Обновлено: 03.07.2024

Это круговая зависимость. Создайте еще один файл, например, database.py, куда вы импортируете курсор.

В тебе access.py попробуй,

Это работает, если оба файла в одном каталоге. но если они находятся в разных каталогах, это не сработает. Если вы хотите импортировать классы из каталогов разного уровня, вы должны импортировать их через main.py

Как уже упоминалось, ваша проблема связана с циклической зависимостью - оба модуля зависят друг от друга - это общая проблема проектирования (у вас не должно быть циклических зависимостей, независимо от используемого языка) и плохо поддерживаемая Python.

В то время как существуют быстрые и грязные технические обходные пути, они только маскируют симптомы, но сами не решают проблему. Существуют различные стратегии избегать циклических зависимостей (например, извлечение общей зависимости для отдельного модуля, как в ответе ex4), и чаще всего вы используете комбинацию thise. В вашем случае очень очевидная проблема заключается в том, что ваш allowed модуль зависит от глобального cursor без уважительной причины. То, что вы должны здесь сделать, это просто передать явно зависимого в качестве аргумента зависимому, то есть:

Эта стратегия (называемая «внедрение зависимостей») не только нарушает циклическую зависимость, но и делает ваш код намного проще для тестирования в изоляции.

Теперь есть еще одна - не связанная, но серьезная - проблема с вашим кодом: код вашего allowed модуля должен зависеть не от cursor , а от самого объекта connection . Первая и главная причина заключается в том, что курсоры не являются реентерабельными, поэтому, если одна функция использует курсор для итерации по проблеме запроса select, а во время итерации вызывает другую функцию, которая использует тот же курсор для любой другой операции, вы получите очень неожиданные результаты. , Кроме того, вам все еще понадобится объект подключения для обработки транзакций. Соединения с базой данных являются дорогостоящими, но курсоры являются дешевыми одноразовыми объектами, поэтому нет веских причин для повторного использования курсора.

Вы не можете импортировать два файла наоборот, например, из класса 1 импортировать Class1 в сценарии 2 и из класса 2 импортировать Class2 в сценарии 1.

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

Порой бывает трудно правильно реализовать import с первого раза, особенно если мы хотим добиться правильной работы на плохо совместимых между собой версиях Python 2 и Python 3. Попытаемся разобраться, что из себя представляют импорты в Python и как написать решение, которое подойдёт под обе версии языка.

Содержание

Ключевые моменты

  • Выражения import производят поиск по списку путей в sys.path .
  • sys.path всегда включает в себя путь скрипта, запущенного из командной строки, и не зависит от текущей рабочей директории.
  • Импортирование пакета по сути равноценно импортированию __init__.py этого пакета.

Основные определения

  • Модуль: любой файл *.py . Имя модуля — имя этого файла.
  • Встроенный модуль: «модуль», который был написан на Си, скомпилирован и встроен в интерпретатор Python, и потому не имеет файла *.py .
  • Пакет: любая папка, которая содержит файл __init__.py . Имя пакета — имя папки.
    • С версии Python 3.3 любая папка (даже без __init__.py ) считается пакетом.

    Пример структуры директорий

    Обратите внимание, что в корневой папке test/ нет файла __init__.py .

    Что делает import

    При импорте модуля Python выполняет весь код в нём. При импорте пакета Python выполняет код в файле пакета __init__.py , если такой имеется. Все объекты, определённые в модуле или __init__.py , становятся доступны импортирующему.

    Встроенные функции Python: какие нужно знать и на какие не стоит тратить время

    Основы import и sys.path

    Вот как оператор import производит поиск нужного модуля или пакета согласно документации Python:

    • директории, содержащей исходный скрипт (или текущей директории, если файл не указан);
    • директории по умолчанию, которая зависит от дистрибутива Python;
    • PYTHONPATH (список имён директорий; имеет синтаксис, аналогичный переменной окружения PATH ).

    Технически документация не совсем полна. Интерпретатор будет искать не только файл (модуль) spam.py , но и папку (пакет) spam .

    Обратите внимание, что Python сначала производит поиск среди встроенных модулей — тех, которые встроены непосредственно в интерпретатор. Список встроенных модулей зависит от дистрибутива Python, а найти этот список можно в sys.builtin_module_names (Python 2 и Python 3). Обычно в дистрибутивах есть модули sys (всегда включён в дистрибутив), math , itertools , time и прочие.

    В отличие от встроенных модулей, которые при поиске проверяются первыми, остальные (не встроенные) модули стандартной библиотеки проверяются после директории запущенного скрипта. Это приводит к сбивающему с толку поведению: возможно «заменить» некоторые, но не все модули стандартной библиотеки. Допустим, модуль math является встроенным модулем, а random — нет. Таким образом, import math в start.py импортирует модуль из стандартной библиотеки, а не наш файл math.py из той же директории. В то же время, import random в start.py импортирует наш файл random.py .

    ABBYY , Удалённо , По итогам собеседования

    Кроме того, импорты в Python регистрозависимы: import Spam и import spam — разные вещи.

    Функцию pkgutil.iter_modules() (Python 2 и Python 3) можно использовать, чтобы получить список всех модулей, которые можно импортировать из заданного пути:

    Чуть подробнее о sys.path

    Чтобы увидеть содержимое sys.path , запустите этот код:

    Документация Python описывает sys.path так:

    Список строк, указывающих пути для поиска модулей. Инициализируется из переменной окружения PYTHONPATH и директории по умолчанию, которая зависит от дистрибутива Python.

    При запуске программы после инициализации первым элементом этого списка, path[0] , будет директория, содержащая скрипт, который был использован для вызова интерпретатора Python. Если директория скрипта недоступна (например, если интерпретатор был вызван в интерактивном режиме или скрипт считывается из стандартного ввода), то path[0] является пустой строкой. Из-за этого Python сначала ищет модули в текущей директории. Обратите внимание, что директория скрипта вставляется перед путями, взятыми из PYTHONPATH .

    Источник: Python 2 и Python 3

    Документация к интерфейсу командной строки Python добавляет информацию о запуске скриптов из командной строки. В частности, при запуске python <script>.py .

    Если имя скрипта ссылается непосредственно на Python-файл, то директория, содержащая этот файл, добавляется в начало sys.path , а файл выполняется как модуль main .

    Источник: Python 2 и Python 3

    Итак, повторим порядок, согласно которому Python ищет импортируемые модули:

    1. Модули стандартной библиотеки (например, math , os ).
    2. Модули или пакеты, указанные в sys.path :
        1. Если интерпретатор Python запущен в интерактивном режиме:
          • sys.path[0] — пустая строка '' . Это значит, что Python будет искать в текущей рабочей директории, из которой вы запустили интерпретатор. В Unix-системах эту директорию можно узнать с помощью команды pwd .

        Если мы запускаем скрипт командой python <script>.py :

        Обратите внимание, что при запуске скрипта для sys.path важна не директория, в которой вы находитесь, а путь к самому скрипту. Например, если в командной строке мы находимся в test/folder и запускаем команду python ./packA/subA/subA1.py , то sys.path будет включать в себя test/packA/subA/ , но не test/ .

        Кроме того, sys.path общий для всех импортируемых модулей. Допустим, мы вызвали python start.py . Пусть start.py импортирует packA.a1 , а a1.py выводит на экран sys.path . В таком случае sys.path будет включать test/ (путь к start.py ), но не test/packA (путь к a1.py ). Это значит, что a1.py может вызвать import other , так как other.py находится в test/ .

        Всё о __init__.py

        У файла __init__.py есть две функции:

        1. Превратить папку со скриптами в импортируемый пакет модулей (до Python 3.3).
        2. Выполнить код инициализации пакета.

        Превращение папки со скриптами в импортируемый пакет модулей

        Чтобы импортировать модуль (или пакет) из директории, которая находится не в директории нашего скрипта (или не в директории, из которой мы запускаем интерактивный интерпретатор), этот модуль должен быть в пакете.

        Как было сказано ранее, любая директория, содержащая файл __init__.py , является пакетом. Например, при работе с Python 2.7 start.py может импортировать пакет packA , но не packB , так как в директории test/packB/ нет файла __init__.py .

        Это не относится к Python 3.3 и выше благодаря появлению неявных пакетов пространств имён. Проще говоря, в Python 3.3+ все папки считаются пакетами, поэтому пустые файлы __init__.py больше не нужны.

        Допустим, packB — пакет пространства имён, так как в нём нет __init__.py . Если запустить интерактивную оболочку Python 3.6 в директории test/ , то мы увидим следующее:

        Выполнение кода инициализации пакета

        В момент, когда пакет или один из его модулей импортируется в первый раз, Python выполняет __init__.py в корне пакета, если такой файл существует. Все объекты и функции, определённые в __init__.py , считаются частью пространства имён пакета.

        Рассмотрим следующий пример:

        Вывод после запуска python start.py :

        Примечание Если a1.py вызовет import a2 , и мы запустим python a1.py , то test/packA/__init__.py не будет вызван, несмотря на то, что a2 вроде бы является частью пакета packA . Это связано с тем, что когда Python выполняет скрипт (в данном случае a1.py ), содержащая его папка не считается пакетом.

        Использование объектов из импортированного модуля или пакета

        Есть 4 разных вида импортов:

        1. import <пакет>
        2. import <модуль>
        3. from <пакет> import <модуль или подпакет или объект>
        4. from <модуль> import <объект>

        Пусть X — имя того, что идёт после import :

        • Если X — имя модуля или пакета, то для того, чтобы использовать объекты, определённые в X , придётся писать X.объект .
        • Если X — имя переменной, то её можно использовать напрямую.
        • Если X — имя функции, то её можно вызвать с помощью X() .

        Опционально после любого выражения import X можно добавить as Y . Это переименует X в Y в пределах скрипта. Учтите, что имя X с этого момента становится недействительным. Частым примером такой конструкции является import numpy as np .

        Аргументом для import может быть как одно имя, так и их список. Каждое из имён можно переименовать с помощью as . Например, следующее выражение будет действительно в start.py : import packA as pA, packA.a1, packA.subA.sa1 as sa1 .

        Пример: нужно в start.py импортировать функцию helloWorld() из sa1.py .

        • Решение 1: from packA.subA.sa1 import helloWorld . Мы можем вызвать функцию напрямую по имени: x = helloWorld() .
        • Решение 2: from packA.subA import sa1 или то же самое import packA.subA.sa1 as sa1 . Для использования функции нам нужно добавить перед её именем имя модуля: x = sa1.helloWorld() . Иногда такой подход предпочтительнее первого, так как становится ясно, из какого модуля взялась та или иная функция.
        • Решение 3: import packA.subA.sa1 . Для использования функции перед её именем нужно добавить полный путь: x = packA.subA.sa1.helloWorld() .

        Прим. перев. После переименования с помощью as новое имя нельзя использовать в качестве имени пакета или модуля для последующих импортов. Иными словами, команда вроде следующей недействительна: import packA as pA, pA.a1 .

        Используем dir() для исследования содержимого импортированного модуля

        После импортирования модуля можно использовать функцию dir() для получения списка доступных в модуле имён. Допустим, мы импортируем sa1 . Если в sa1.py есть функция helloWorld() , то dir(sa1) будет включать helloWorld :

        Импортирование пакетов

        Импортирование пакета по сути равноценно импортированию его __init__.py . Вот как Python на самом деле видит пакет:

        После импорта становятся доступны только те объекты, что определены в __init__.py пакета. Поскольку в packB нет такого файла, от import packB (в Python 3.3.+) будет мало толку, так как никакие объекты из этого пакета не становятся доступны. Последующий вызов модуля packB.b1 приведёт к ошибке, так как он ещё не был импортирован.

        Абсолютный и относительный импорт

        При абсолютном импорте используется полный путь (от начала корневой папки проекта) к желаемому модулю.

        При относительном импорте используется относительный путь (начиная с пути текущего модуля) к желаемому модулю. Есть два типа относительных импортов:

        1. При явном импорте используется формат from .<модуль/пакет> import X , где символы точки . показывают, на сколько директорий «вверх» нужно подняться. Одна точка . показывает текущую директорию, две точки .. — на одну директорию выше и т. д.
        2. Неявный относительный импорт пишется так, как если бы текущая директория была частью sys.path . Такой тип импортов поддерживается только в Python 2.

        В документации Python об относительных импортах в Python 3 написано следующее:

        Единственный приемлемый синтаксис для относительных импортов — from .[модуль] import [имя] . Все импорты, которые начинаются не с точки . , считаются абсолютными.

        Источник: What’s New in Python 3.0

        В качестве примера допустим, что мы запускаем start.py , который импортирует a1 , который импортирует other , a2 и sa1 . Тогда импорты в a1.py будут выглядеть следующим образом:

        Явные относительные импорты:

        Неявные относительные импорты (не поддерживаются в Python 3):

        Учтите, что в относительных импортах с помощью точек . можно дойти только до директории, содержащей запущенный из командной строки скрипт (не включительно). Таким образом, from .. import other не сработает в a1.py . В результате мы получим ошибку ValueError: attempted relative import beyond top-level package .

        Как правило, абсолютные импорты предпочтительнее относительных. Они позволяют избежать путаницы между явными и неявными импортами. Кроме того, любой скрипт с явными относительными импортами нельзя запустить напрямую:

        Имейте в виду, что относительные импорты основаны на имени текущего модуля. Так как имя главного модуля всегда "__main__" , модули, которые должны использоваться как главный модуль приложения, должны всегда использовать абсолютные импорты.

        Источник: Python 2 и Python 3

        Примеры

        Пример 1: sys.path известен заранее

        Если вы собираетесь вызывать только python start.py или python other.py , то прописать импорты всем модулям не составит труда. В данном случае sys.path всегда будет включать папку test/ . Таким образом, все импорты можно писать относительно этой папки.

        Пример: файлу в проекте test нужно импортировать функцию helloWorld() из sa1.py .

        Решение: from packA.subA.sa1 import helloWorld (или любой другой эквивалентный синтаксис импорта).

        Пример 2: sys.path мог измениться

        Зачастую нам требуется как запускать скрипт напрямую из командной строки, так и импортировать его как модуль в другом скрипте. Как вы увидите далее, здесь могут возникнуть проблемы, особенно в Python 3.

        Пример: пусть start.py нужно импортировать a2 , которому нужно импортировать sa2 . Предположим, что start.py всегда запускается напрямую, а не импортируется. Также мы хотим иметь возможность запускать a2 напрямую.

        Звучит просто, не так ли? Нам всего лишь нужно выполнить два импорта: один в start.py и другой в a2.py .

        Проблема: это один из тех случаев, когда sys.path меняется. Когда мы выполняем start.py , sys.path содержит test/ , а при выполнении a2.py sys.path содержит test/packA/ .

        С импортом в start.py нет никаких проблем. Так как этот модуль всегда запускается напрямую, мы знаем, что при его выполнении в sys.path всегда будет test/ . Тогда импортировать a2 можно просто с помощью import packA.a2 .

        С импортом в a2.py немного сложнее. Когда мы запускаем start.py напрямую, sys.path содержит test/ , поэтому в a2.py импорт будет выглядеть как from packA.subA import sa2 . Однако если запустить a2.py напрямую, то в sys.path уже будет test/packA/ . Теперь импорт вызовет ошибку, так как packA не является папкой внутри test/packA/ .

        Вместо этого мы могли бы попробовать from subA import sa2 . Это решает проблему при запуске a2.py напрямую, однако теперь создаёт проблему при запуске start.py . В Python 3 это приведёт к ошибке, потому что subA не находится в sys.path (в Python 2 это не вызовет проблемы из-за поддержки неявных относительных импортов).

        Запускаем from packA.subA import sa2 from subA import sa2
        start.py Нет проблем В Py2 нет проблем, в Py3 ошибка ( subA не в test/ )
        a2.py Ошибка ( packA не в test/packA/ ) Нет проблем

        Использование относительного импорта from .subA import sa2 будет иметь тот же эффект, что и from packA.subA import sa2 .

        Вряд ли для этой проблемы есть чистое решение, поэтому вот несколько обходных путей:

        1. Использовать абсолютные импорты относительно директории test/ (т. е. средняя колонка в таблице выше). Это гарантирует, что запуск start.py напрямую всегда сработает. Чтобы запустить a2.py напрямую, запустите его как импортируемый модуль, а не как скрипт:

        1. В консоли смените директорию на test/ .
        2. Запустите python -m packA.a2 .

        2. Использовать абсолютные импорты относительно директории test/ (средняя колонка в таблице). Это гарантирует, что запуск start.py напрямую всегда сработает. Чтобы запустить a2.py напрямую, можно изменить sys.path в a2.py , чтобы включить test/packA/ перед импортом sa2 .

        Примечание Обычно этот метод работает, однако в некоторых случаях переменная __file__ может быть неправильной. В таком случае нужно использовать встроенный пакет inspect . Подробнее в этом ответе на StackOverflow.

        3. Использовать только Python 2 и неявные относительные импорты (последняя колонка в таблице).

        4. Использовать абсолютные импорты относительно директории test/ и добавить её в переменную среды PYTHONPATH . Это решение не переносимо, поэтому лучше не использовать его. О том, как добавить директорию в PYTHONPATH , читайте в этом ответе.

        Пример 3: sys.path мог измениться (вариант 2)

        А вот ещё одна проблема посложнее. Допустим, модуль a2.py никогда не надо запускать напрямую, но он импортируется start.py и a1.py , которые запускаются напрямую.

        В этом случае первое решение из примера выше не сработает. Тем не менее, всё ещё можно использовать остальные решения.

        Пример 4: импорт из родительской директории

        Если мы не изменяем PYTHONPATH и стараемся не изменять sys.path программно, то сталкиваемся со следующим основным ограничением импортов в Python: при запуске скрипта напрямую невозможно импортировать что-либо из его родительской директории.

        Например, если бы нам пришлось запустить python sa1.py , то этот модуль не смог бы ничего импортировать из a1.py без вмешательства в PYTHONPATH или sys.path .

        На первый взгляд может показаться, что относительные импорты (например from .. import a1 ) помогут решить эту проблему. Однако запускаемый скрипт (в данном случае sa1.py ) считается «модулем верхнего уровня». Попытка импортировать что-либо из директории над этим скриптом приведёт к ошибке ValueError: attempted relative import beyond top-level package .

        Для решения этой проблемы лучше её не создавать и избегать написания скриптов, которые импортируют из родительской директории. Если этого нельзя избежать, то предпочтительным обходным путём является изменение sys.path .

        Python 2 vs Python 3

        Мы разобрали основные отличия импортов в Python 2 и Python 3. Они ещё раз изложены здесь наряду с менее важными отличиями:

        Оператор импорта Python используется для импорта модулей, которые мы хотим использовать в нашей программе. Модули Python являются сценариями Python, содержащая функции утилиты, типы, классы и т. Д. Существует множество модулей, которые мы регулярно используем в программах Python, такие как SYS, OS, коллекции и т. Д.

        Python Import.

        Если мы хотим импортировать встроенные модули Python или любой третий модуль, установленный с помощью менеджера пакета, такой как PIP, то мы можем очень легко импортировать и использовать их в нашей программе.

        Python ищет модули и пакеты в sys.path имущество. Этот путь всегда содержит текущий каталог, откуда выполняется скрипт, поэтому любой модуль в текущем каталоге может быть импортирован как есть.

        Импорт Python чувствителен к регистру, поэтому Импорт SYS и Импорт SYS Ищите разные модули для импорта.

        Python ищет модуль в встроенные модули сначала. Если не найден, то он ищет модули в текущем каталоге. Так что если у нас есть Матем.пи Файл в том же каталоге, что и наш главный скрипт, то он будет загружен, когда Импортировать математику называется, если «Math» модуль не находится в встроенных модулях. Вы можете получить список встроенных модулей, использующих sys.buittin_module_names Отказ Ниже изображения изображены встроенные модули в моей установке Python.

        Класс для импорта Python/функции из модуля

        Мы можем импортировать определенные классы из модуля тоже. Таким образом, мы можем импортировать определенные части модуля и использовать его. Это также помогает в письменной форме беглый код. Мы можем достичь этого, используя из ключевого слова с оператором импорта.

        Python Import пользовательский модуль

        Когда мы создаем сценарий Python, мы можем импортировать его в другой сценарий Python, используя его имя. Допустим, мы имеем следующую структуру каталогов с несколькими сценариями Python.

        У нас есть следующие функции, определенные в Utils.py файл.

        Мы можем импортировать его в python_import_examples.py и использовать его функции.

        Импорт Питона как

        Мы можем определить наше имя для импортируемого модуля, используя Импорт как утверждение.

        Результатом будет такой же, как более ранняя программа.

        Python Import из другого каталога

        Если скрипт Python мы импортируем, находится в одном каталоге, то мы можем импортировать легко так же, как встроенные модули. Однако, если сценарий Python присутствует в другом каталоге, то мы можем использовать ImportLib Библиотека для импорта их в виде модуля.

        Допустим, наш Strutils.py имеет следующие функции:

        Теперь давайте посмотрим, как использовать ImportLib для импорта этого сценария Python в наш пример.

        Класс импорта Python из другого файла

        Мы можем импортировать сценарии и использовать классы, определенные в них, используя ImportLib. Допустим, у нас есть занятия Человек и Студент Определяется в myclasses.py файл.

        Вот пример кода, в котором я использую более раннюю определенную функцию для импорта этого сценария и использовать его классы.

        Обратите внимание, что мы можем сохранить любое имя для модуля, который мы импортируем, это похоже на использование Импорт как утверждение.

        Есть еще один способ импорта скриптов из другого каталога, используя sys модуль.

        Это полезно, когда мы хотим импортировать только определенные классы и функции из импортируемого файла. Также использование этого кода намного проще понять.

        Резюме

        Заявление о импорте Python позволяет нам импортировать модули, сценарии Python, определенные классы и функции из модулей. Это очень легко использовать, и, поскольку большую часть времени мы работаем над встроенными модулями или модулями, установленными с помощью PIP, нам не нужно писать логику для загрузки сценариев из другого каталога.

        Я могу заставить этот код работать, но я все еще запутался, почему он не будет работать первым, как я пытался.

        Я занимаюсь питоном, потому что мой тезис будет закодирован в нем (делайте некоторые интересные вещи с интерфейсами Arduino и ПК). Я пытаюсь импортировать класс из другого файла в свою основную программу, чтобы я мог создавать объекты. Оба файла находятся в одном каталоге. Это, вероятно, проще, если вы посмотрите на код на данный момент.

        Вот основной класс ArduinoBot

        Спасибо за помощь.

        рассмотрите файл ( example.py ):

        Теперь в вашей основной программе, если вы это сделаете:

        что следует импортировать из файла example.py ? Только example класса? должен ли класс foo прийти тоже? Значение будет слишком неоднозначным, если import module вытащил все пространство имен модулей прямо в ваше текущее пространство имен.

        Идея заключается в том, что пространства имен прекрасны. Они сообщают вам, откуда появился класс/функция/данные. Они также позволяют группировать связанные вещи вместе (или, что то же самое, они помогают вам не разделить отдельные вещи!). Модуль устанавливает пространство имен, и вы указываете python точно, как вы хотите довести это пространство имен в текущем контексте (пространстве имен) так, как вы используете import .

        from. import. as. говорит, приносите только то, что я указываю прямо в свое пространство имен, но даю ему новое имя здесь.

        Наконец, import. просто говорит, что этот модуль можно использовать в текущем пространстве имен, но держите его отдельно. Это наиболее распространенная форма производственного кода из-за (по крайней мере) 2 причин.

        • Это предотвращает столкновения имен. У вас может быть локальный класс с именем foo который не будет конфликтовать с foo в example.py Вы получаете доступ к этому через example.foo
        • Это позволяет легко проследить, из какого модуля появился класс для отладки.

        В этом случае, чтобы получить доступ к example класса из example.py , вы также можете:

        но вы также можете получить foo :

        Импорт не работает, как вы думаете. Он работает так, как он документирован, чтобы работать, поэтому есть очень простое средство для вашей проблемы, но тем не менее:

        Это ищет модуль (или пакет) на пути импорта, выполняет код модуля в новом пространстве имен и затем связывает сам объект модуля с именем ArduinoBot в текущем пространстве имен. Это означает, что глобальная переменная модуля с именем ArduinoBot в модуле ArduinoBot теперь будет доступна в импорте пространства имен как ArduinoBot.ArduinoBot .

        Это загружает и выполняет модуль, как указано выше, но не связывает объект модуля с именем ArduinoBot . Вместо этого он ищет глобальную переменную модуля ArduinoBot внутри модуля и связывает любой объект, который ссылается на имя ArduinoBot в текущем пространстве имен.

        Как и выше, это загружает и выполняет модуль без привязки объекта модуля к любому имени в текущем пространстве имен. Затем он ищет все глобальные переменные модуля и связывает их все с тем же именем в текущем пространстве имен.

        Эта последняя форма очень удобна для интерактивной работы в оболочке python, но обычно считается плохим стилем в реальной разработке, потому что неясна, какие имена она фактически связывает. Учитывая, что он импортирует все глобальное в импортированный модуль, включая любые имена, которые он импортировал в глобальном масштабе, очень быстро становится чрезвычайно сложно узнать, какие имена находятся в сфере охвата или откуда они пришли, если вы используете этот стиль повсеместно.

        Вместо того, чтобы работать против этого, вы должны использовать контейнерность модулей, чтобы вы могли группировать связанные вещи в модуль. Это может показаться раздражающим, когда у вас есть только один класс в файле, но когда вы начинаете вкладывать несколько классов и функций в один файл, вы увидите, что фактически не хотите, чтобы все эти вещи были автоматически импортированы, когда вы import module , потому что тогда все из всех модулей будет конфликтовать с другими вещами. Модули служат полезной функцией для разделения различных функций.

        Для вашего примера вопрос, который вы должны задать себе, заключается в следующем: если код такой простой и компактный, почему вы не поместили его в один файл?

        Сам модуль является объектом. Последний подход действительно работает, если вы получаете доступ к своему классу в качестве члена модуля. Либо если следующее будет работать и может быть уместно, в зависимости от того, что вам нужно от импортированных предметов:

        Как упоминалось в комментариях, ваш модуль и класс обычно не имеют одинакового имени в python. Это нечто большее, чем Java, и иногда может привести к некоторой путанице.

        Читайте также: