Qu'est-ce que init.py pour?

Qu'est-ce que __init__.py pour un répertoire source Python?

1492
demandé sur guaka 2009-01-15 23:09:09

11 réponses

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

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

1030
répondu Loki 2016-02-05 16:23:19

les fichiers nommés __init__.py sont utilisés pour marquer les répertoires sur le disque en tant que 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 fichier __init__.py , Python ne cherchera plus de sous-modules dans ce répertoire, donc les tentatives d'importation du module échoueront.

le fichier __init__.py est habituellement vide, mais peut être utilisé pour exporter des parties sélectionnées du paquet sous un nom plus commode, tenir des fonctions de convenance, etc. Compte tenu de l'exemple ci-dessus, le contenu du module init peut être consulté en tant que

import spam

basé sur ce

615
répondu caritos 2017-03-28 16:01:34

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

un exemple

voici un exemple de 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

mon __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)

puisque je définis Session ici, je peux démarrer une nouvelle session en utilisant la syntaxe ci-dessous. Ce code serait le même que celui exécuté depuis l'intérieur ou l'extérieur du répertoire de paquets "base de données".

from database import Session
session = Session()

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

from database.create_session import Session
session = Session()

Lire la suite

il y a un très intéressant fil de reddit 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 les fichiers __init__.py devraient être très minces pour éviter de violer la philosophie" explicite est mieux qu'implicite".

374
répondu Nathan Gould 2013-09-24 17:55:49

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 la hiérarchie de votre paquet.

    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
    

    puis d'autres peuvent appeler add () par

    from your_package import add
    

    sans connaître fil1, comme

    from your_package.file1 import add
    
  2. si vous voulez que quelque chose soit initialisé; par exemple, la journalisation (qui doit être placé au niveau supérieur):

    import logging.config
    logging.config.dictConfig(Your_logging_config)
    
113
répondu flycee 2017-01-02 14:29:05

le fichier __init__.py permet à Python de traiter les répertoires qui le contiennent comme des modules.

de plus, c'est le premier fichier à être chargé dans un module, donc vous pouvez l'utiliser pour exécuter le code que vous voulez exécuter à chaque fois qu'un module est chargé, ou spécifier les sous-modules à exporter.

87
répondu Can Berk Güder 2009-01-15 20:22:58

depuis Python 3.3, __init__.py n'est plus nécessaire pour définir les répertoires comme paquets Python importables.

Vérifier PEP 420: Implicite de l'espace de Noms de Paquets :

support natif pour les répertoires de paquets qui n'ont pas besoin de fichiers marqueurs __init__.py et qui peuvent s'étendre automatiquement sur plusieurs segments de chemin (inspiré de diverses approches tierces aux paquets namespace, 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

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/

est-ce que ... init__.py pas nécessaire pour les paquets en Python 3?

48
répondu zeekvfu 2017-05-23 12:10:41

en Python La définition de paquet est très simple. Comme Java, la structure hiérarchique et la structure du répertoire sont identiques. Mais vous devez avoir __init__.py dans un paquet. Je vais expliquer le fichier __init__.py 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. Il indique que le répertoire doit être considérée 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 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 hiérarchie et avons appelé module_n1 la fonction. Nous pouvons utiliser __init__.py dans subPackage_b comme ceci:

__all__ = ['module_n2', 'module_n3']

après 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

donc en utilisant * importing, le module package est soumis au contenu __init__.py .

46
répondu Marcus Thornton 2014-03-17 18:20:39

__init__.py traitera le répertoire qu'il contient comme un module chargeable.

pour les personnes qui préfèrent lire le code, j'ai mis commentaire de deux-Bit Alchemist 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
>>> 
36
répondu B.Mr.W. 2017-05-23 12:10:41

qu'est-Ce que __init__.py est-il utilisé?

l'utilisation principale de __init__.py est d'initialiser les paquets Python. La façon la plus simple de le démontrer est de jeter un coup d'oeil à 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 au-dessus de l'inclusion du fichier __init__.py dans un répertoire indique à l'interpréteur Python que le répertoire doit être traité comme un Python paquet

Ce qui se passe dans __init__.py ?

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

une chose courante à faire dans votre __init__.py est d'importer certaines Classes, fonctions, etc. dans le niveau du paquet pour qu'elles puissent être importées de manière conviviale à partir du paquet.

In exemple ci-dessus nous pouvons dire que file.py il a le dossier 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 au niveau du paquet de rendre les sous-paquets/modules disponibles avec la variable __all__ . Lorsque l'interphone voit une variable __all__ définie dans un __init__.py il importe les modules énumérés dans la variable __all__ lorsque vous faites:

from package import *

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

__all__ = ['submodule1', 'submodule2']

avec la variable __all__ peuplée comme ça, quand vous exécutez

from subpackage import *

il importerait sous-Module1 et sous-module2.

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

33
répondu Chirag Maliwal 2018-03-03 04:40:14

Il facilite l'importation d'autres fichiers python. Quand vous avez placé ce fichier dans un répertoire (par exemple stuff)contenant d'autres fichiers py, alors vous pouvez faire quelque chose comme importer des trucs.autre.

root\
    stuff\
         other.py

    morestuff\
         another.py

sans ce __init__.py dans le répertoire, vous ne pouviez pas importer other.py, parce que Python ne sait pas où est le code source de stuff et ne peut pas le reconnaître comme un paquet.

25
répondu Epitaph 2013-06-08 10:45:40

bien que Python fonctionne sans un fichier __init__.py , vous devez toujours en inclure un.

Il spécifie un paquet doit être traité comme un module, donc l'inclure (même si elle est vide).

Il ya aussi un cas où vous pouvez effectivement utiliser un __init__.py fichier:

Imaginez que vous aviez la structure de fichier suivante:

main_methods 
    |- methods.py

et methods.py contenait ceci:

def foo():
    return 'foo'

pour utiliser foo() vous auriez besoin de l'un des suivants:

from main_methods.methods import foo # Call with foo()
from main_methods import methods # Call with methods.foo()
import main_methods.methods # Call with main_methods.methods.foo()

peut-être que vous avez besoin (ou que vous voulez) de garder methods.py à l'intérieur de main_methods (runtimes/dependencies par exemple) mais vous voulez seulement importer main_methods .


si vous avez changé le nom de methods.py en __init__.py alors vous pouvez utiliser foo() par il suffit d'importer main_methods :

import main_methods
print(main_methods.foo()) # Prints 'foo'

cela fonctionne parce que __init__.py est considéré comme faisant partie du paquet.


certains paquets Python font effectivement cela. Un exemple est avec JSON , où l'exécution de import json importe réellement __init__.py du paquet json ( voir la structure du fichier paquet ici ):

code Source: Lib/json/__init__.py

8
répondu Simon 2018-05-18 07:48:38