Réponses:
Il faisait partie intégrante d'un package ( ancien, "package normal" antérieur à 3.3 , et non plus récent "package d'espace de noms" 3.3+ ).
Python définit deux types de packages, les packages standard et les packages d'espace de noms. Les packages réguliers sont des packages traditionnels tels qu'ils existaient dans Python 3.2 et versions antérieures. Un package standard est généralement implémenté comme un répertoire contenant un
__init__.py
fichier. Lorsqu'un package standard est importé, ce__init__.py
fichier est implicitement exécuté et les objets qu'il définit sont liés à des noms dans l'espace de noms du package. Le__init__.py
fichier peut contenir le même code Python que tout autre module peut contenir, et Python ajoutera des attributs supplémentaires au module lors de son importation.
Mais cliquez simplement sur le lien, il contient un exemple, plus d'informations et une explication des packages d'espace de noms, le type de packages sans __init__.py
.
sys.path.insert(0, '/path/to/datetime')
, en remplaçant ce chemin par le chemin vers le répertoire que vous venez de créer. Maintenant, essayez quelque chose comme from datetime import datetime;datetime.now()
. Vous devriez obtenir une AttributeError (car il importe maintenant votre fichier vierge). Si vous deviez répéter ces étapes sans créer le fichier init vide, cela ne se produirait pas. C'est ce que l'on veut empêcher.
from datetime import datetime
sans erreur. C'est bien depuis la version 2.3!
builtins
liste les fonctions et classes intégrées, pas les modules intégrés (cf. docs.python.org/3/tutorial/modules.html#the-dir-function ). Si vous voulez lister les modules intégrés , faites-le import sys; print(sys.builtin_module_names)
(cf. docs.python.org/3/library/sys.html#sys.builtin_module_names ).
Les fichiers nommés __init__.py
sont utilisés pour marquer les répertoires sur le disque en tant que répertoires de packages 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 en module.py
tant que
import spam.module
ou
from spam import module
Si vous supprimez le __init__.py
fichier, Python ne recherchera 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 package sous un nom plus pratique, conserver des fonctions pratiques, etc. Étant donné l'exemple ci-dessus, le contenu du module init est accessible comme
import spam
basé sur cela
__init__.py
était requis sous Python 2.X et est toujours requis sous Python 2.7.12 (je l'ai testé) mais il n'est plus requis à partir de (prétendument) Python 3.3 et n'est plus requis sous Python 3.4.3 (I testé). Voir stackoverflow.com/questions/37139786 pour plus de détails.
__init__.py
.
setup.py
et que vous l'utilisez find_packages()
il faut en avoir __init__.py
dans chaque répertoire. Voir stackoverflow.com/a/56277323/7127824
En plus d'étiqueter un répertoire en tant que package Python et de le définir __all__
, __init__.py
vous permet de définir n'importe quelle variable au niveau du package. Cela est souvent pratique si un package définit quelque chose qui sera importé fréquemment, à la manière d'une API. Ce modèle favorise l'adhésion à la philosophie Pythonique "plat est meilleur que imbriqué".
Voici un exemple de l'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 package "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 exécuté de l'intérieur ou de l'extérieur du répertoire du package "base de données".
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 package de base de données, et de démarrer de nouvelles sessions en utilisant:
from database.create_session import Session
session = Session()
Il y a un fil reddit assez intéressant couvrant les utilisations appropriées d' __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 __init__.py
fichiers doivent être très fins pour éviter de violer la philosophie "explicite vaut mieux qu'implicite".
engine
, sessionmaker
, create_engine
Et os
peut tout aussi être importés d' database
aujourd'hui ... semble que vous avez fait un gâchis de cet espace de noms.
__all__ = [...]
pour limiter ce qui est importé avec import *
. Mais à part cela, oui, vous vous retrouvez avec un espace de noms de premier niveau en désordre.
Il y a 2 raisons principales pour __init__.py
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 vos packages.
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
Si vous voulez que quelque chose soit initialisé; par exemple, la journalisation (qui devrait être placée au niveau supérieur):
import logging.config
logging.config.dictConfig(Your_logging_config)
__init__.py
peut être utile parfois, mais pas toujours.
Le __init__.py
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 le code que vous souhaitez exécuter à chaque fois qu'un module est chargé, ou spécifier les sous-modules à exporter.
Depuis Python 3.3, il __init__.py
n'est plus nécessaire de définir les répertoires en tant que packages Python importables.
Vérifiez PEP 420: packages implicites d'espace de noms :
Prise en charge native des répertoires de packages qui ne nécessitent pas de
__init__.py
fichiers de marqueurs et peuvent s'étendre automatiquement sur plusieurs segments de chemin (inspirés de diverses approches tierces des packages d'espace 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
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/
Is __init__. py non requis pour les packages en Python 3?
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. Il indique que le répertoire doit être considéré comme un package. 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 package de hiérarchie et appelé module_n1 la fonction. Nous pouvons 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 package du module est soumis au __init__.py
contenu.
from package_x.subPackage_b.module_n1 import function_X
Bien que Python fonctionne sans __init__.py
fichier, vous devez toujours en inclure un.
Il spécifie qu'un paquet doit être traité comme un module, alors incluez-le donc (même s'il est vide).
Il y a aussi un cas où vous pouvez réellement utiliser un __init__.py
fichier:
Imaginez que vous ayez la structure de fichiers suivante:
main_methods
|- methods.py
Et methods.py
contenait ceci:
def foo():
return 'foo'
Pour l'utiliser, foo()
vous auriez besoin de l'un des éléments 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 y avez-vous besoin (ou voulez-vous) de rester à l' methods.py
intérieur main_methods
(runtimes / dépendances par exemple) mais vous voulez seulement importer main_methods
.
Si vous avez changé le nom de methods.py
en, __init__.py
vous pouvez l'utiliser foo()
en important simplement main_methods
:
import main_methods
print(main_methods.foo()) # Prints 'foo'
Cela fonctionne car __init__.py
est traité comme faisant partie du package.
Certains packages Python le font. Un exemple est avec JSON , où l'exécution import json
est en fait une importation à __init__.py
partir du json
package ( voir la structure du fichier du package ici ):
Code source:
Lib/json/__init__.py
__init__.py
traitera le répertoire dans lequel il se trouve comme un module chargeable.
Pour les personnes qui préfèrent lire le code, je mets ici le commentaire de Two-Bit Alchemist .
$ 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
>>>
Il facilite l'importation d'autres fichiers python. Lorsque vous avez placé ce fichier dans un répertoire (disons stuff) contenant d'autres fichiers py, vous pouvez faire quelque chose comme importer stuff.other.
root\
stuff\
other.py
morestuff\
another.py
Sans cela __init__.py
à l'intérieur du répertoire, vous ne pourriez pas importer other.py, car Python ne sait pas où se trouve le code source du contenu et ne peut pas le reconnaître en tant que package.
Un __init__.py
fichier facilite les importations. Quand un __init__.py
est présent dans un package, la fonction a()
peut être importée à partir d'un fichier b.py
comme ceci:
from b import a
Sans cela, cependant, vous ne pouvez pas importer directement. Vous devez modifier le chemin du système:
import sys
sys.path.insert(0, 'path/to/b.py')
from b import a