Подтвердить что ты не робот

Импорт пакетов в Python

Я, вероятно, пропустил что-то очевидное, но в любом случае:

Когда вы импортируете пакет, например os в python, вы можете использовать любые подмодули/подпакеты с места в карьер. Например, это работает:

>>> import os
>>> os.path.abspath(...)

Однако у меня есть собственный пакет, который структурирован следующим образом:

FooPackage/
  __init__.py
  foo.py

и здесь та же логика не работает:

>>> import FooPackage
>>> FooPackage.foo
AttributeError: 'module' object has no attribute 'foo'

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

4b9b3361

Ответ 1

Вам нужно импортировать подмодуль:

import FooPackage.foo

То, что вы делаете, ищет foo в FooPackage/__init__.py. Вы могли бы решить это, поставив import FooPackage.foo as foo (или from . import foo) в FooPackage/__init__.py, тогда Python сможет найти там foo. Но я рекомендую использовать мое первое предложение.

Ответ 2

Когда вы импортируете FooPackage, Python ищет каталоги на PYTHONPATH, пока не найдет файл с именем FooPackage.py или каталог с именем FooPackage, содержащий файл с именем __init__.py. Однако, найдя каталог пакета, он не сканирует этот каталог и автоматически импортирует все .py файлы.

Есть две причины такого поведения. Во-первых, при импорте модуля выполняется код Python, который может занять время, память или иметь побочные эффекты. Поэтому вы можете импортировать a.b.c.d без обязательного импорта всего огромного пакета a. Разработчик пакета должен решить, должен ли __init__.py явно импортировать свои модули и подпакеты, чтобы они всегда были доступны, или же или оставляет клиентскую программу возможностью выбирать и выбирать загружаемую.

Второе немного более тонкое, а также шоустоппер. Без явного оператора import (либо в FooPackage/__init__.py, либо в клиентской программе) Python не обязательно знает, какое имя должно импортировать foo.py as. В нечувствительной к регистру файловой системе (например, используемой в Windows) это может представлять собой модуль с именем foo, foo, foo, foo, foo, foo, foo или foo. Все они являются действительными, отличными идентификаторами Python, поэтому Python просто не располагает достаточной информацией из файла, чтобы знать, что вы имеете в виду. Поэтому для того, чтобы вести себя последовательно во всех системах, для этого требуется явный оператор импорта, чтобы уточнить имя, даже в файловых системах, где доступна полная информация о случаях.

Ответ 3

Вам нужно добавить from . import foo в файл __init__.py в вашем пакете.

Ответ 4

Существуют некоторые важные заблуждения, которые необходимо решить, в частности, с терминологией. Во-первых, обычно, когда вы думаете, что импортируете package в python, то, что вы фактически импортируете, является module. Вы должны использовать термин " package когда вы думаете о подструктуре файловой системы, которая поможет вам организовать ваш код. Но с точки зрения кода, всякий раз, когда вы импортируете package, Python рассматривает его как модуль. Все пакеты являются модулями. Не все модули являются пакетами. Модуль с атрибутом __path__ считается пакетом.

Вы можете проверить, что os является модулем. Чтобы подтвердить это, вы можете:

import os
print(type(os)) # will print: <type 'module'>

В вашем примере, когда вы import FooPackage, FooPackage рассматривается и считается модулем, а его атрибуты (функции, классы и т.д.) Предположительно определены в __init__.py. Поскольку ваш __init__.py пуст, он не может найти foo.

За пределами import заявлений вы не можете использовать '.' нотация для адреса модулей внутри модулей. Единственное исключение происходит, если module импортируется в файл родительского пакета предполагаемого __init__.py. Чтобы было ясно, давайте сделаем несколько примеров здесь:

Рассмотрите свою первоначальную структуру:

FooPackage/
  __init__.py
  foo.py

Случай 1: __init__.py - пустой файл

#FooPackage imported as a module
import FooPackage 

#foo is not a name defined in '__init__.py'. Error
FooPackage.foo 

#FooPackage.foo imported as a module
import FooPackage.foo

#Error, foo has not been imported. To be able to use foo like this,
#you need to do: import FooPackage.foo as foo
foo.anything

#Not error, if anything is defined inside foo.py
FooPackage.foo.anything

Случай 2: __init__.py имеет import foo строки в нем:

import FooPackage

#Now this is good. 'foo' is sort of considered to be an attribute of 
#FooPackage
FooPackage.foo

Теперь предположим, что foo больше не является module, а function которую вы определяете в __init__.py. если вы import FooPackage.foo, это вызовет ошибку, говоря, что foo не является модулем.

Ответ 5

Вы можете импортировать пакет из библиотеки с помощью оператора import.

синтаксис: import module_name

     ex: import math

Вы можете импортировать только определенный метод из пакета с помощью синтаксиса ударов

Синтаксис

: from module_name import function_name

     ex: from math import radians