Je ne connais pas Python et je n'arrive toujours pas à comprendre pourquoi nous avons besoin d'un __init__.py
fichier pour importer des modules. J'ai parcouru d'autres questions et réponses, telles que this .
Ce qui m'embrouille, c'est que je peux importer mes modules sans __init__py
, donc pourquoi en ai-je besoin ?
Mon exemple,
index.py
modules/
hello/
hello.py
HelloWorld.py
index.py,
import os
import sys
root = os.path.dirname(__file__)
sys.path.append(root + "/modules/hello")
# IMPORTS MODULES
from hello import hello
from HelloWorld import HelloWorld
def application(environ, start_response):
results = []
results.append(hello())
helloWorld = HelloWorld()
results.append(helloWorld.sayHello())
output = "<br/>".join(results)
response_body = output
status = '200 OK'
response_headers = [('Content-Type', 'text/html'),
('Content-Length', str(len(response_body)))]
start_response(status, response_headers)
return [response_body]
modules/hello/hello.py,
def hello():
return 'Hello World from hello.py!'
modules/hello/HelloWorld.py,
# define a class
class HelloWorld:
def __init__(self):
self.message = 'Hello World from HelloWorld.py!'
def sayHello(self):
return self.message
Résultat,
Hello World from hello.py!
Hello World from HelloWorld.py!
Il suffit de ces deux lignes,
root = os.path.dirname(__file__)
sys.path.append(root + "/modules/hello")
Sans aucun des __init__py
. Quelqu'un peut-il expliquer pourquoi cela fonctionne de cette façon?
Si __init__py
est la bonne façon, que dois-je faire/changer dans mon code?
Je pense que c'est une bonne 'réponse' pour ce que je n'ai pas compris.
myMath/
__init__.py
adv/
__init__.py
sqrt.py
fib.py
add.py
subtract.py
multiply.py
divide.py
myMath/__ init __. py
from add import add
from divide import division
from multiply import multiply
from subtract import subtract
from adv.fib import fibonacci
from adv.sqrt import squareroot
index.py
import sys
sys.path.append('C:\Users\mdriscoll\Documents')
import mymath
print mymath.add(4,5)
print mymath.division(4, 2)
print mymath.multiply(10, 5)
print mymath.fibonacci(8)
print mymath.squareroot(48)
__init__.py
est pour packages. Un package contient une collection de modules associés. Si vous n'avez qu'un seul module que vous souhaitez utiliser, vous n'avez pas besoin d'utiliser __init__.py
; il suffit de mettre le single .py
fichier quelque part sur le chemin du système et vous pouvez l'importer.
Le but des packages n'est pas seulement de vous permettre d'importer les modules qu'ils contiennent. Il s'agit de regrouper les modules. Le principal avantage de ceci est que, si un module se trouve à l'intérieur d'un package, ce module peut importer d'autres modules du package à l'aide d'importations relatives. Si tu as foo.py
et bar.py
dans le même paquet, alors foo
peut simplement faire from . import bar
. Cela rend les importations intra-package plus compactes et plus faciles à réorganiser si vous restructurez le package ou changez son nom.
En outre, un avantage évident est. . . si vous en faites un package, vous n'avez pas à le faire sys.path
trucs à chaque fois que vous voulez en importer quelque chose.
Je pense que cela pourrait être dû à la version Python que vous utilisez. J'ai fait quelques expériences et j'ai découvert que la structure suivante était la suivante:
jedrzej@jedrzej-UX303LB ~/temp $ tree .
.
├── main.py
└── packages
├── file.py
└── file.pyc
1 directory, 5 files
contenu de main.py:
import packages.file as p
p.fun()
et le contenu de file.py:
import sys
def fun():
print(sys.path)
Lorsque j'exécute main.py
avec Python 2.7.12 J'obtiens ImportError
pendant l'exécution de main.py
avec Python 3.5.2 fonctionne simplement.
Après avoir ajouté __init__.py
dans le répertoire des packages, le code fonctionne avec les deux versions de Python.
Basé sur ce lien: Depuis Python 3.3
Autoriser les packages d'espace de noms implicites signifie que l'exigence de fournir un
__init__.py
le fichier peut être complètement supprimé
Fichiers nommés __init__.py
sont utilisés pour marquer les répertoires sur le disque comme Python. Si vous avez les fichiers
modules/spam/__init__.py
modules/spam/module.py
et modules
est sur votre chemin, vous pouvez importer le code dans module.py
as
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
le 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 avec
import spam
Et enfin voici ce que la documentation officielle a à dire sur ce fichier:
Le __init__.py
les fichiers sont nécessaires pour que Python traite les répertoires comme contenant des packages; cela est fait pour empêcher les répertoires avec un nom commun, tel que chaîne, de masquer involontairement des modules valides qui se produisent plus tard sur le module chemin de recherche. Dans le cas le plus simple, __init__.py
peut simplement être un fichier vide, mais il peut également exécuter le code d'initialisation du package ou définir le __all__
variable, décrite plus loin.