Для чего в пакетах модулей python в файле init py служит список all

Обновлено: 07.07.2024

Синтаксис функции Python __init __()

  • Ключевое слово def используется для его определения, потому что это функция.
  • Первый аргумент относится к текущему объекту. Он связывает экземпляр с методом init(). Обычно его называют «я», чтобы следовать соглашению об именах. Вы можете узнать больше об этом в собственной переменной Python.
  • Аргументы метода init() необязательны. Мы можем определить конструктор с любым количеством аргументов.

Давайте рассмотрим, что мы создаем класс с именем Car. У автомобиля могут быть такие атрибуты, как «цвет», «модель», «скорость» и т. Д., А также такие методы, как «старт», «ускорение», «переключение передач» и т. Д.

Поэтому мы использовали метод __init__ конструктора для инициализации атрибутов класса.

Примеры

Давайте посмотрим на несколько примеров функции конструктора в разных сценариях.

1. Класс без конструктора

Вот еще один пример, подтверждающий, что конструктор суперкласса вызывается для инициализации экземпляра подкласса.

2. Простой конструктор без аргументов

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

3. Конструктор классов с аргументами

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

4. Конструктор классов с наследованием

  • Мы обязаны вызвать конструктор суперкласса.
  • Мы можем использовать функцию super() для вызова функции конструктора суперкласса.
  • Мы также можем использовать имя суперкласса для вызова его метода init().

5. Цепочка конструкторов с многоуровневым наследованием

6. С множественным наследованием

Мы не можем использовать super() для доступа ко всем суперклассам в случае множественного наследования. Лучшим подходом было бы вызвать функцию конструктора суперклассов, используя их имя класса.

Python не поддерживает несколько конструкторов

Python не поддерживает несколько конструкторов, в отличие от других популярных объектно-ориентированных языков программирования, таких как Java.

Мы можем определить несколько методов __init __(), но последний из них переопределит предыдущие определения.

Может ли функция Python __init __() что-то вернуть?

Если мы попытаемся вернуть значение, отличное от None, из функции __init __(), это вызовет ошибку TypeError.

Если мы изменим оператор return на return None тогда код будет работать без каких-либо исключений.

I have been using Python more and more, and I keep seeing the variable __all__ set in different __init__.py files. Can someone explain what this does?

13.5k 3 3 gold badges 18 18 silver badges 19 19 bronze badges

11 Answers 11

Linked to, but not explicitly mentioned here, is exactly when __all__ is used. It is a list of strings defining what symbols in a module will be exported when from <module> import * is used on the module.

For example, the following code in a foo.py explicitly exports the symbols bar and baz :

These symbols can then be imported like so:

If the __all__ above is commented out, this code will then execute to completion, as the default behaviour of import * is to import all symbols that do not begin with an underscore, from the given namespace.

NOTE: __all__ affects the from <module> import * behavior only. Members that are not mentioned in __all__ are still accessible from outside the module and can be imported with from <module> import <member> .

8,453 7 7 gold badges 71 71 silver badges 71 71 bronze badges 16.4k 4 4 gold badges 29 29 silver badges 23 23 bronze badges @JohnCole baz is function object and baz() will run the function object The goal is to illustrate that the symbols are exported. Whether it executes the function or not is secondary. @JulioCezarSilva off topic a bit, but worth noting that for classes and functions you can use the __name__ property

It's a list of public objects of that module, as interpreted by import * . It overrides the default of hiding everything that begins with an underscore.

83.9k 17 17 gold badges 115 115 silver badges 135 135 bronze badges Objects that begin with an underscore, or are not mentioned in __all__ if __all__ is present, are not exactly hidden; they can be seen and accessed perfectly normally if you know their names. It is only in the case of an "import *", which is not recommended anyway, that the distinction carries any weight. @BrandonRhodes: that’s not exactly true either: It’s recommended to only import modules that you know to be designed for import * (like e.g. tk ). A good hint if this is the case is the presence of __all__ or names starting with underscore in the module’s code. To summarize: If you have __all__ , import * will import everything in the __all__ , otherwise, it will import everything that does not start with an underscore.

Explain all in Python?

I keep seeing the variable __all__ set in different __init__.py files.

What does this do?

What does __all__ do?

It declares the semantically "public" names from a module. If there is a name in __all__ , users are expected to use it, and they can have the expectation that it will not change.

It also will have programmatic effects:

import *

__all__ in a module, e.g. module.py :

means that when you import * from the module, only those names in the __all__ are imported:

Documentation tools

Documentation and code autocompletion tools may (in fact, should) also inspect the __all__ to determine what names to show as available from a module.

__init__.py makes a directory a Python package

The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path.

In the simplest case, __init__.py can just be an empty file, but it can also execute initialization code for the package or set the __all__ variable.

So the __init__.py can declare the __all__ for a package.

A package is typically made up of modules that may import one another, but that are necessarily tied together with an __init__.py file. That file is what makes the directory an actual Python package. For example, say you have the following files in a package:

Let's create these files with Python so you can follow along - you could paste the following into a Python 3 shell:

And now you have presented a complete api that someone else can use when they import your package, like so:

And the package won't have all the other implementation details you used when creating your modules cluttering up the package namespace.

__all__ in __init__.py

After more work, maybe you've decided that the modules are too big (like many thousands of lines?) and need to be split up. So you do the following:

First make the subpackage directories with the same names as the modules:

Move the implementations:

create __init__.py s for the subpackages that declare the __all__ for each:

And now you still have the api provisioned at the package level:

And you can easily add things to your API that you can manage at the subpackage level instead of the subpackage's module level. If you want to add a new name to the API, you simply update the __init__.py , e.g. in module_2:

And if you're not ready to publish Baz in the top level API, in your top level __init__.py you could have:

and if your users are aware of the availability of Baz , they can use it:

but if they don't know about it, other tools (like pydoc) won't inform them.

You can later change that when Baz is ready for prime time:

By default, Python will export all names that do not start with an _ . You certainly could rely on this mechanism. Some packages in the Python standard library, in fact, do rely on this, but to do so, they alias their imports, for example, in ctypes/__init__.py :

Using the _ convention can be more elegant because it removes the redundancy of naming the names again. But it adds the redundancy for imports (if you have a lot of them) and it is easy to forget to do this consistently - and the last thing you want is to have to indefinitely support something you intended to only be an implementation detail, just because you forgot to prefix an _ when naming a function.

I personally write an __all__ early in my development lifecycle for modules so that others who might use my code know what they should use and not use.

Most packages in the standard library also use __all__ .

It makes sense to stick to the _ prefix convention in lieu of __all__ when:

  • You're still in early development mode and have no users, and are constantly tweaking your API.
  • Maybe you do have users, but you have unittests that cover the API, and you're still actively adding to the API and tweaking in development.

The downside of using __all__ is that you have to write the names of functions and classes being exported twice - and the information is kept separate from the definitions. We could use a decorator to solve this problem.

I got the idea for such an export decorator from David Beazley's talk on packaging. This implementation seems to work well in CPython's traditional importer. If you have a special import hook or system, I do not guarantee it, but if you adopt it, it is fairly trivial to back out - you'll just need to manually add the names back into the __all__

So in, for example, a utility library, you would define the decorator:

and then, where you would define an __all__ , you do this:

And this works fine whether run as main or imported by another function.

And API provisioning with import * will work too:


315k 78 78 gold badges 381 381 silver badges 316 316 bronze badges Cross reference: I mentioned your decorator in this CW answer to the question of how to write an @export decorator. This has single handedly been the most helpful answer I have seen in regards to helping a relatively new python developer understand the process of importing modules/packages with __init__.py and the use of __all__ @MikeC then maybe you should generate your __all__ too - but then I would say you have an unstable API. This would be something to have some comprehensive acceptance tests on.

I'm just adding this to be precise:

All other answers refer to modules. The original question explicitely mentioned __all__ in __init__.py files, so this is about python packages.

Generally, __all__ only comes into play when the from xxx import * variant of the import statement is used. This applies to packages as well as to modules.

The behaviour for modules is explained in the other answers. The exact behaviour for packages is described here in detail.

In short, __all__ on package level does approximately the same thing as for modules, except it deals with modules within the package (in contrast to specifying names within the module). So __all__ specifies all modules that shall be loaded and imported into the current namespace when us use from package import * .

The big difference is, that when you omit the declaration of __all__ in a package's __init__.py , the statement from package import * will not import anything at all (with exceptions explained in the documentation, see link above).

On the other hand, if you omit __all__ in a module, the "starred import" will import all names (not starting with an underscore) defined in the module.

27.7k 14 14 gold badges 74 74 silver badges 104 104 bronze badges When all contains [foo, bar] and in test.py file if we use: from package import *, then, do foo and bar get imported in the local namespace of test.py or in the foo and bars own namespace?

It also changes what pydoc will show:

I declare __all__ in all my modules, as well as underscore internal details, these really help when using things you've never used before in live interpreter sessions.

12k 4 4 gold badges 45 45 silver badges 53 53 bronze badges

A module is a .py file meant to be imported.

A package is a directory with a __init__.py file. A package usually contains modules.

__all__ lets humans know the "public" features of a module. [@AaronHall] Also, pydoc recognizes them. [@Longpoke]

from module import *

See how swiss and cheddar are brought into the local namespace, but not gouda :

Without __all__ , any symbol (that doesn't start with an underscore) would have been available.

import module

from module import names

import module as localname

In the __init__.py file of a package __all__ is a list of strings with the names of public modules or other objects. Those features are available to wildcard imports. As with modules, __all__ customizes the * when wildcard-importing from the package. [@MartinStettner]

Here's an excerpt from the Python MySQL Connector __init__.py :

The default case, asterisk with no __all__ for a package, is complicated, because the obvious behavior would be expensive: to use the file system to search for all modules in the package. Instead, in my reading of the docs, only the objects defined in __init__.py are imported:

If __all__ is not defined, the statement from sound.effects import * does not import all submodules from the package sound.effects into the current namespace; it only ensures that the package sound.effects has been imported (possibly running any initialization code in __init__.py ) and then imports whatever names are defined in the package. This includes any names defined (and submodules explicitly loaded) by __init__.py . It also includes any submodules of the package that were explicitly loaded by previous import statements.

And lastly, a venerated tradition for stack overflow answers, professors, and mansplainers everywhere, is the bon mot of reproach for asking a question in the first place:

Wildcard imports . should be avoided, as they [confuse] readers and many automated tools.

3,607 3 3 gold badges 17 17 silver badges 48 48 bronze badges


13.5k 8 8 gold badges 74 74 silver badges 96 96 bronze badges

The public names defined by a module are determined by checking the module's namespace for a variable named __all__ ; if defined, it must be a sequence of strings which are names defined or imported by that module. The names given in __all__ are all considered public and are required to exist. If __all__ is not defined, the set of public names includes all names found in the module's namespace which do not begin with an underscore character ("_"). __all__ should contain the entire public API. It is intended to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module).

358k 94 94 gold badges 596 596 silver badges 786 786 bronze badges

__all__ affects from <module> import * statements.

Consider this example:

(Implicit) If we don't define __all__ , then from foo import * will only import names defined in foo/__init__.py .

(Explicit) If we define __all__ = [] , then from foo import * will import nothing.

(Explicit) If we define __all__ = [ <name1>, . ] , then from foo import * will only import those names.

Note that in the implicit case, python won't import names starting with _ . However, you can force importing such names using __all__ .

You can view the Python document here.

7,984 7 7 gold badges 55 55 silver badges 81 81 bronze badges

__all__ is used to document the public API of a Python module. Although it is optional, __all__ should be used.

Here is the relevant excerpt from the Python language reference:

The public names defined by a module are determined by checking the module’s namespace for a variable named __all__ ; if defined, it must be a sequence of strings which are names defined or imported by that module. The names given in __all__ are all considered public and are required to exist. If __all__ is not defined, the set of public names includes all names found in the module’s namespace which do not begin with an underscore character ('_'). __all__ should contain the entire public API. It is intended to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module).

PEP 8 uses similar wording, although it also makes it clear that imported names are not part of the public API when __all__ is absent:

To better support introspection, modules should explicitly declare the names in their public API using the __all__ attribute. Setting __all__ to an empty list indicates that the module has no public API.

[. ]

Imported names should always be considered an implementation detail. Other modules must not rely on indirect access to such imported names unless they are an explicitly documented part of the containing module's API, such as os.path or a package's __init__ module that exposes functionality from submodules.

Furthermore, as pointed out in other answers, __all__ is used to enable wildcard importing for packages:

The import statement uses the following convention: 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.

Я использую Python все больше и больше вижу переменную __all__ в разных файлах __init__.py . Может кто-нибудь объяснить, что это делает?

Это список общедоступных объектов этого модуля, интерпретируемый import * . Он отменяет умолчание, скрывая все, что начинается с подчеркивания.

Связано, но явно не упомянуто здесь, именно тогда, когда используется __all__ . Это список строк, определяющих, какие символы в модуле будут экспортироваться, когда from <module> import * используется from <module> import * .

Например, следующий код в foo.py явно экспортирует bar символов и baz :

Эти символы затем можно импортировать так:

Если __all__ выше закомментирован, этот код будет выполняться до конца, так как стандартное поведение import * состоит в том, чтобы импортировать все символы, которые не начинаются с подчеркивания, из заданного пространства имен.

ПРИМЕЧАНИЕ. __all__ влияет только на поведение from <module> import * . Члены, которые не упомянуты в __all__ , по-прежнему доступны извне модуля и могут быть импортированы from <module> import <member> .

Я просто добавляю это, чтобы быть точным:

Все остальные ответы относятся к модулю. Исходный вопрос явно упоминается __all__ в __init__.py файлах, так что это касается пакетов python.

Как правило, __all__ включается только тогда, когда используется from xxx import * вариант оператора import . Это относится как к пакетам, так и к модулям.

Поведение для модулей объясняется в других ответах. Точное поведение для пакетов описано здесь.

Короче говоря, __all__ на уровне пакета делает примерно то же самое, что и для модулей, за исключением того, что он касается модулей внутри пакета (в отличие от указания имен в модуле). Таким образом, __all__ указывает все модули, которые должны быть загружены и импортированы в текущее пространство имен, когда мы используем from package import * .

Большая разница в том, что когда вы опускаете объявление __all__ в пакете __init__.py , оператор from package import * ничего не будет импортировать (с исключениями, описанными в документации, см. ссылку выше).

С другой стороны, если вы опускаете __all__ в модуле, "избранный импорт" будет импортировать все имена (не начиная с подчеркивания), определенные в модуле.

Объяснить __all__ в Python?

Я вижу переменную __all__ в разных __init__.py файлах.

Что это делает?

Он объявляет семантически "общедоступные" имена из модуля. Если в __all__ есть имя, пользователи должны использовать его, и они могут ожидать, что он не изменится.

Он также будет иметь программные аффекты:

import *

__all__ в модуле, например. module.py :

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

Инструменты документации

Документация и инструменты автозаполнения кода могут (по сути, должны также) также проверять __all__ , чтобы определить, какие имена будут отображаться как доступные с модуля.

Файлы __init__.py необходимы, чтобы Python рассматривал каталоги как содержащие пакеты; это делается для того, чтобы предотвратить каталоги с общим именем, такие как строка, от непреднамеренного скрытия допустимых модулей, которые появляются позже на пути поиска модуля.

В простейшем случае __init__.py может быть просто пустым файлом, но он также может выполнять код инициализации для пакета или устанавливать переменную __all__ .

Таким образом, __init__.py может объявить __all__ для пакета.

Пакет обычно состоит из модулей, которые могут импортировать друг друга, но которые обязательно связаны с файлом __init__.py . Этот файл делает каталог актуальным пакетом Python. Например, скажем, что у вас есть следующее:

в __init__.py вы пишете:

и в module_1 у вас есть:

и в module_2 у вас есть:

И теперь вы представили полный api, который может использовать кто-то другой, когда они импортируют ваш пакет, например:

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

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

И в каждом __init__.py вы объявляете __all__ , например. в модуле_1:

И module_2 __init__.py :

И вы можете легко добавить вещи в свой API, которые вы можете управлять на уровне подпакетов, а не на уровне модуля подпакета. Если вы хотите добавить новое имя в API, вы просто обновите __init__.py , например. в модуле_2:

И если вы не готовы опубликовать Baz в API верхнего уровня, на верхнем уровне __init__.py вы могли бы:

и если ваши пользователи знают о доступности Baz , они могут использовать его:

но если они об этом не знают, другие инструменты (например, pydoc) не сообщают об этом.

Вы можете позже изменить это, когда Baz готов к прайм-тайму:

По умолчанию Python будет экспортировать все имена, которые не начинаются с _ . Вы, конечно, могли бы положиться на этот механизм. Некоторые пакеты в стандартной библиотеке Python, на самом деле, полагаются на это, но для этого они, как и их импорт, например, в ctypes/__init__.py :

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

Я лично пишу __all__ в начале жизненного цикла разработки для модулей, чтобы другие, которые могли использовать мой код, знали, что они должны использовать и не использовать.

В большинстве пакетов стандартной библиотеки также используется __all__ .

Имеет смысл придерживаться условного обозначения _ вместо __all__ , когда:

  • Вы все еще находитесь в раннем режиме разработки и не имеете пользователей, и постоянно настраиваете свой API.
  • Возможно, у вас есть пользователи, но у вас есть unittests, которые охватывают API, и вы по-прежнему активно добавляете API и настраиваете его в разработке.

Недостатком использования __all__ является то, что вам нужно дважды записывать имена функций и классов, экспортируемых дважды, и информация хранится отдельно от определений. Мы могли бы использовать декоратор для решения этой проблемы.

У меня появилась идея, что такой декоратор-декор из Дэвида Бэзли говорит на упаковке. Эта реализация, похоже, хорошо работает в традиционном импортере CPython. Если у вас есть специальный крючок или система импорта, я не гарантирую этого, но если вы его усыновите, довольно просто вернуться - вам просто нужно вручную добавить имена обратно в __all__

Так, например, в библиотеке утилиты вы должны определить декоратор:

а затем, где вы определяете __all__ , вы делаете это:

И это прекрасно работает независимо от того, запущен ли он как основной или импортирован другой функцией.

И подготовка API с помощью import * тоже будет работать:

Он также изменяет то, что pydoc будет показывать:

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

Публичные имена, определенные модулем, определяются путем проверки пространства имен модулей для переменной с именем __all__ ; если определено, это должна быть последовательность строк, которые являются именами, определенными или импортированными этим модулем. Имена, указанные в __all__ , считаются общедоступными и должны существовать. Если __all__ не определен, набор открытых имен включает все имена, найденные в пространстве имен модулей, которые не начинаются с символа подчеркивания ( "_" ). __all__ должен содержать весь открытый API. Он предназначен для того, чтобы избежать случайного экспорта элементов, которые не являются частью API (например, библиотечные модули, которые были импортированы и использованы в модуле).

Модуль - это файл .py предназначенный для импорта.

Пакет - это каталог с файлом __init__.py . Пакет обычно содержит модули.

__all__ позволяет людям знать "общедоступные" функции модуля. [ @AaronHall ] Кроме того, Pydoc распознает их. [ @Longpoke ]

из модуля импорта *

Посмотрите, как swiss и cheddar попадают в локальное пространство имен, но не gouda :

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

модуль импорта

из имени модуля импорта

импортировать модуль как локальное имя

В файле __init__.py пакета __all__ представляет собой список строк с именами открытых модулей или других объектов. Эти функции доступны для импорта по шаблону. Как и в случае с модулями, __all__ настраивает * при импорте шаблона из пакета. [ @MartinStettner ]

Вот выдержка из Python MySQL Connector __init__.py :

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

Если __all__ не определено, оператор from sound.effects import * не импортирует все подмодули из пакета sound.effects в текущее пространство имен; он только гарантирует, что пакет sound.effects был импортирован (возможно, выполняется любой код инициализации в __init__.py ), а затем импортирует любые имена, определенные в пакете. Это включает в себя любые имена, определенные (и явно загруженные подмодули) с помощью __init__.py . Он также включает любые подмодули пакета, которые были явно загружены предыдущими операторами импорта.

Следует избегать импорта символов подстановки. поскольку они [запутывают] читателей и многие автоматизированные инструменты.

__all__ влияет на __all__ from <module> import * .

Рассмотрим этот пример:

(Неявный) Если мы не определим __all__ , то from foo import * будет импортироваться только имена, определенные в foo/__init__.py .

(Явный) Если мы определим __all__ = [] , то from foo import * ничего не импортирует.

(Явный) Если мы определим __all__ = [ <name1>. ] , то from foo import * будут импортированы только эти имена.

Обратите внимание, что в неявном случае python не будет импортировать имена, начинающиеся с _ . Однако вы можете принудительно импортировать такие имена, используя __all__ .

Вы можете просмотреть документ Python здесь.

__all__ используется для документирования открытого API модуля Python. Хотя это необязательно, следует использовать __all__ .

Вот соответствующий отрывок из ссылка на язык Python:

Публичные имена, определенные модулем, определяются путем проверки пространства имен модулей для переменной с именем __all__ ; если определено, это должна быть последовательность строк, которые являются именами, определенными или импортированными этим модулем. Имена, указанные в __all__ , считаются общедоступными и должны существовать. Если __all__ не определен, набор общедоступных имен включает все имена, найденные в пространстве имен модулей, которые не начинаются с символа подчеркивания ('_'). __all__ должен содержать весь открытый API. Он предназначен для того, чтобы избежать случайного экспорта элементов, которые не являются частью API (например, библиотечные модули, которые были импортированы и использованы в модуле).

PEP 8 использует аналогичную формулировку, хотя он также дает понять, что импортированные имена не являются частью общедоступного API, когда __all__ отсутствует

Чтобы лучше поддерживать интроспекцию, модули должны явно объявлять имена в своем открытом API с помощью атрибута __all__ . Установка __all__ в пустой список указывает, что модуль не имеет открытого API.

[. ]

Импортированные имена всегда должны рассматриваться как детализация реализации. Другие модули не должны полагаться на косвенный доступ к таким импортированным именам, если они не являются явно документированной частью содержащего API модуля, такого как os.path или модуль пакета __init__ , который предоставляет функции из подмодулей.

Кроме того, как указано в других ответах, __all__ используется для включения подстановочного импорта для пакетов:

Оператор import использует следующее соглашение: если код пакета __init__.py определяет список с именем __all__ , он считается списком имен модулей, которые должны быть импортированы, когда встречается from package import * .

Как создать пакет Python?

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

Что мы можем сохранить в пакете?

  • Файл инициализации;
  • Модули;
  • Скрипты;
  • Любой другой тип файлов.

Можно ли создавать подпакеты?

Да, мы можем создать пакет внутри другого пакета. Мы также должны следовать правилам упаковки, чтобы создать подпакет.

Примеры

Давайте рассмотрим несколько примеров создания и использования пакетов.

1. Создание пакета

Python пакеты

2. Добавление модулей

Мы хотим добавить эти модули в наши пакеты. Просто скопируйте эти файлы в каталог пакетов, где вы хотите сохранить эти модули.

добавление модуля в пакет

3. Импорт пакета

Синтаксис для импорта модуля Python внутри пакета:

Python использует переменную sys.path для поиска пакетов и модулей. Текущий каталог является частью переменной sys.path . Поэтому мы будем хранить наш скрипт python в каталоге python-packages. В противном случае нам придется добавить местоположение пакета в переменную sys.path .

Вот код my_script.py для доступа к модулям из пакетов и вызова их функций.

Модуль Импорта

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

Вот обновленный пример доступа к модулям «math» и «str_utils» в нашей программе.

Из Модуля Импорта Пакетов

4. Импорт * из пакета

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

В этом случае Python ищет в sub_package2 пакеты, модули и функции. Это может вызвать побочные эффекты из-за импорта того, чего вы не хотите. Кроме того, это очень долгий процесс.

Мы можем определить список импортируемых модулей, создав переменную __all__ в файле __init__.py.

утилиты / __ init__.py:

утилиты / строки / __ init__.py:

Обновленный код my_script.py:

Файл Инициализации Всех Модулей

Обратите внимание, что код python в __init__.py выполняется первым, когда пакеты инициализируются и импортируются.

Как добавить пакет в системный путь

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

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

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