Импорт * в Python 3.7 с использованием файла __init__.py

Прежде всего, вот моя структура каталогов:

Root
   - models 
        car.py 
        __init__.py 
   hello.py 

Внутри __init__.py у меня есть следующее:

__all__ = ["car"]

Внутри hello.py пытаюсь импортировать все из папки моделей:

from models import *

car = Car()

Это дает мне ошибку:

Traceback (most recent call last):
  File "hello.py", line 4, in <module>
    car = Car()
NameError: name 'Car' is not defined

Что я делаю неправильно?

FWIW Я бы вообще рекомендовал никогда не импортировать *. Никогда не надо, и "явное лучше, чем неявное". Это также совет, который дает PEP 8: «Следует избегать импорта подстановочных знаков (from <module> import *), поскольку они не позволяют понять, какие имена присутствуют в пространстве имен, что сбивает с толку как читателей, так и многие автоматизированные инструменты».

Daniel Pryden 24.09.2018 02:37
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
4 474
5

Ответы 5

Вам нужно будет указать, какой класс вы хотите импортировать в атрибут __all__ вашего файла __init__.py. См. Пример ниже:

from car import *
__all__ = ["Car"]

Теперь я получаю следующее: из импорта моделей * AttributeError: модуль 'models' не имеет атрибута 'Car'

john doe 24.09.2018 01:48

Куда идут эти строки? У меня уже есть все = ["Car"] внутри файла в этом.py.

john doe 24.09.2018 03:00

@johndoe: Это содержимое вашего файла __init__.py, и не забывайте, это Car, а не car, как в вашем примере.

Jonathan Gagne 20.10.2018 18:27

Если вы хотите иметь прямой доступ к классу Car в hello.py после того, как вы сделаете from models import *, в файле __init__.py поместите from models.car import Car.

__all__, с другой стороны, как правило перечисляет имена модули, как у вас выше. Вы можете изменить hello.py следующим образом, и ваш текущий __init__.py, состоящий из __all__ = ["car"], будет работать:

from models import *
car_obj = car.Car() # Reference module.class instead of just the class

Из питона документы:

if a package’s __init__.py code defines a list named __all__, it is taken to be the list of module names that should be imported when from package import * is encountered.

Это означает, что ваш hello.py только что импортировал модуль car в свое пространство имен, нет - класс Car. Следовательно, это сработает.

from models import *
auto = car.Car()

Вы пропустили там один шаг.

Пытаться:

from models import *

car = car.Car()

Или попробуйте:

from models.car import *

car = Car()

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

В вашем случае Car не входит в сферу вашего __init__.py. Так что это бессмысленно.

Чтобы решить эту проблему, вам нужно импортировать Car в область __init__.py, вот и все.

Я понимаю, что вы думаете, что просто используя __all__, вы можете получить прямой доступ к классу в car.py, но это неправда. __all__ не делает ничего, кроме контролировать экспорт в текущем объеме.

Другие вопросы по теме