Question À quoi sert __init__.py?


Quel est __init__.py dans un répertoire source Python?


1411
2018-01-15 20:09


origine


Réponses:


C'est une partie d'un paquet. Voici la documentation.

le __init__.py les fichiers sont requis pour que Python traite les répertoires comme contenant des paquets; ceci est fait pour empêcher les répertoires avec un nom commun, tels que string, de masquer involontairement des modules valides qui se produisent plus tard (plus profond) sur le chemin de recherche du module. Dans le cas le plus simple, __init__.py peut juste être un fichier vide, mais il peut également exécuter le code d'initialisation pour le paquet ou définir le __all__ variable, décrite plus tard.


975
2018-01-15 20:13



Fichiers nommés __init__.py sont utilisés pour marquer les répertoires sur le disque comme des répertoires de paquets Python. Si vous avez les fichiers

mydir/spam/__init__.py
mydir/spam/module.py

et mydir est sur votre chemin, vous pouvez importer le code dans module.py comme

import spam.module

ou

from spam import module

Si vous supprimez le __init__.py Python ne cherchera plus de sous-modules dans ce répertoire, donc les tentatives d'importation du module échoueront.

le __init__.py fichier est généralement vide, mais peut être utilisé pour exporter des parties sélectionnées du paquet sous un nom plus pratique, tenir des fonctions de commodité, etc. Étant donné l'exemple ci-dessus, le contenu du module init peut être accédé comme

import spam

basé sur ce


597
2017-11-07 03:31



En plus d'étiqueter un répertoire en tant que paquet Python et en définissant __all__, __init__.py vous permet de définir n'importe quelle variable au niveau du package. Cela est souvent pratique si un paquetage définit quelque chose qui sera importé fréquemment, de manière API. Ce modèle favorise l'adhérence à la philosophie Pythonic "flat is better than nested".

Un exemple

Voici un exemple d'un de mes projets, dans lequel j'importe fréquemment un sessionmaker appelé Session pour interagir avec ma base de données. J'ai écrit un paquet "base de données" avec quelques modules:

database/
    __init__.py
    schema.py
    insertions.py
    queries.py

ma __init__.py contient le code suivant:

import os

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)

Depuis que je définis Session ici, je peux commencer une nouvelle session en utilisant la syntaxe ci-dessous. Ce code serait exécuté de la même manière à l'intérieur ou à l'extérieur du répertoire du paquet "database".

from database import Session
session = Session()

Bien sûr, c'est une petite commodité - l'alternative serait de définir Session dans un nouveau fichier comme "create_session.py" dans mon paquet de base de données, et démarrer de nouvelles sessions en utilisant:

from database.create_session import Session
session = Session()

En lire plus

Il y a un fil de reddit assez intéressant couvrant les utilisations appropriées de __init__.py ici:

http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/

L'opinion majoritaire semble être que __init__.py Les fichiers doivent être très fins pour éviter de violer la philosophie «explicite est mieux que implicite».


366
2017-09-24 10:38



Il y a 2 raisons principales pour __init__.py

  1. Pour plus de commodité: les autres utilisateurs n'auront pas besoin de connaître l'emplacement exact de vos fonctions dans votre hiérarchie de paquets.

    your_package/
      __init__.py
      file1.py/
      file2.py/
        ...
      fileN.py
    
    # in __init__.py
    from file1 import *
    from file2 import *
    ...
    from fileN import *
    
    # in file1.py
    def add():
        pass
    

    alors d'autres peuvent appeler add () par

    from your_package import add
    

    sans connaître file1, comme

    from your_package.file1 import add
    
  2. Si vous voulez que quelque chose soit initialisé; par exemple, la journalisation (qui devrait être mis dans le niveau supérieur):

    import logging.config
    logging.config.dictConfig(Your_logging_config)
    

103
2018-04-08 08:29



le __init__.py le fichier fait que Python traite les répertoires le contenant comme des modules.

En outre, il s'agit du premier fichier à être chargé dans un module, vous pouvez donc l'utiliser pour exécuter du code que vous souhaitez exécuter chaque fois qu'un module est chargé ou spécifier les sous-modules à exporter.


87
2018-01-15 20:22



Depuis Python 3.3, __init__.py n'est plus nécessaire de définir des répertoires comme des paquets Python importables.

Vérifier PEP 420: Paquets d'espace de noms implicites:

Prise en charge native des répertoires de packages ne nécessitant pas __init__.py fichiers de marqueurs et peuvent s'étendre automatiquement sur plusieurs segments de chemin (inspirés par diverses approches tierces aux paquets d'espaces de noms, comme décrit dans PEP 420)

Voici le test:

$ mkdir -p /tmp/test_init
$ touch /tmp/test_init/module.py /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
├── module.py
└── __init__.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

$ rm -f /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
└── module.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

les références:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
__init__.py n'est-il pas requis pour les paquets en Python 3? 


45
2017-10-12 06:36



En Python, la définition de package est très simple. Comme Java, la structure hiérarchique et la structure de répertoires sont les mêmes. Mais vous devez avoir __init__.py dans un paquet. Je vais expliquer le __init__.py fichier avec l'exemple ci-dessous:

package_x/
|--  __init__.py
|--    subPackage_a/
|------  __init__.py
|------  module_m1.py
|--    subPackage_b/
|------  __init__.py
|------  module_n1.py
|------  module_n2.py
|------  module_n3.py

__init__.py peut être vide, tant qu'il existe. Cela indique que le répertoire doit être considéré comme un paquet. Bien sûr, __init__.py peut également définir le contenu approprié.

Si nous ajoutons une fonction dans module_n1:

def function_X():
    print "function_X in module_n1"
    return

Après l'exécution:

>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()

function_X in module_n1 

Ensuite, nous avons suivi le paquet de la hiérarchie et appelé la fonction module_n1. On peut utiliser __init__.py dans subPackage_b comme ceci:

__all__ = ['module_n2', 'module_n3']

Après l'exécution:

>>>from package_x.subPackage_b import * 
>>>module_n1.function_X()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named module_n1

Par conséquent, en utilisant * l'importation, le module package est soumis à __init__.py contenu.


44
2018-01-09 11:45



__init__.py traitera le répertoire dans lequel il se trouve en tant que module chargeable.

Pour les personnes qui préfèrent lire le code, je mets Alchimiste à deux bits commenter ici.

$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$ 
$ rm /tmp/mydir/spam/__init__.py*
$ 
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>> 

35
2018-01-03 17:41



À quoi sert __init__.py?

L'utilisation principale de __init__.py est d'initialiser les paquets Python. La façon la plus simple de le démontrer est de regarder la structure d'un module Python standard.

package/
    __init__.py
    file.py
    file2.py
    file3.py
    subpackage/
        __init__.py
        submodule1.py
        submodule2.py

Comme vous pouvez le voir dans la structure ci-dessus, l'inclusion de __init__.py le fichier dans un répertoire indique à l'interpréteur Python que le répertoire doit être traité comme un paquet Python

Ce qui se passe __init__.py?

__init__.py peut être un fichier vide, mais il est souvent utilisé pour effectuer l'installation nécessaire pour le paquet (importer des choses, charger les choses dans le chemin, etc).

Une chose commune à faire dans votre __init__.py est d'importer les Classes, fonctions, etc. sélectionnées dans le niveau du paquet afin qu'elles puissent être importées de façon pratique à partir du paquet.

Dans l'exemple ci-dessus, nous pouvons dire que file.py a le fichier de classe. Donc, sans rien dans notre __init__.py vous importeriez avec cette syntaxe:

from package.file import File

Cependant, vous pouvez importer le fichier dans votre __init__.py pour le rendre disponible au niveau du paquet:

# in your __init__.py
from file import File

# now import File from package
from package import File

Une autre chose à faire est de faire des sous-paquets / modules au niveau du paquet avec le __all__ variable. Lorsque l'interpètre voit un __all__ variable définie dans un __init__.py il importe les modules listés dans le __all__ variable lorsque vous faites:

from package import *

__all__est une liste contenant les noms des modules que vous voulez importer avec import * en regardant à nouveau notre exemple ci-dessus si nous voulions importer les sous-modules dans le sous-paquet __all__ variable dans subpackage/__init__.py serait:

__all__ = ['submodule1', 'submodule2']

Avec le __all__ variable peuplée comme ça, quand vous effectuez

from subpackage import *

il importerait submodule1 et submodule2.

Comme vous pouvez le voir __init__.py peut être très utile en plus de sa fonction principale d'indiquer qu'un répertoire est un module.

Référence


26
2017-12-17 06:09