Lorsque vous touchez Python, vous ne pouvez pas vraiment faire la différence entre un module et un package. Surtout lors de l'utilisation d'un IDE appelé PyCharm, il se comporte étrangement.
Par conséquent, je voudrais résumer la lutte entre le package et le module afin que je puisse y revenir plus tard.
Tout d'abord, touchons le module.
Les modules représentent les «fichiers» en Python.
En d'autres termes, si vous créez un fichier appelé ʻadd.py, ce sera un module appelé ʻadd
.
En séparant les fonctions pour chaque module, il est possible d'éviter de gonfler les fonctions dans un seul fichier.
Actuellement, nous utilisons une telle structure de répertoires.
Dans un répertoire appelé Python_Tutorial Contient les éléments suivants:
.
├── __pycache__
├── calc
│ ├── add.py
│ ├── calc_main.py
│ ├── mul.py
│ └── sub.py
└── main.py
Ecrivez le module dans le répertoire calc Essayez ensuite d'appeler un autre module de calcul depuis calc_main. Après cela, essayez d'utiliser main.py directement sous Python_Tutorial.
add.py, mul.py, sub.py Préparer.
print('add.py')
print(__name__)
def add(x, y):
return x + y
if __name__ == '__main__':
print(add(10, 20))
print('sub.py')
print(__name__)
def sub(x, y):
return x - y
if __name__ == '__main__':
print(sub(10, 20))
print('mul.py')
print(__name__)
def mul(x, y):
return x * y
if __name__ == '__main__':
print(mul(10, 20))
avec add.py etc.
if __name__ == '__main__':
print(mul(10, 20))
Est attaché, mais qu'est-ce que c'est?
Il contient le "nom lors de l'exécution du fichier $ f $ .py".
Par exemple, essayez d'exécuter add.py. puis,
add.py
__main__
30
Est sortie.
En effet, il est exécuté à partir du fichier $ f $ = add, et main est défini dans name du fichier exécutable.
Sachez que name dans le fichier d'origine de l'exécution sera toujours main.
Essayez d'exécuter add, sub, mul du même répertoire depuis calc_main.py.
calc_main.py
import add
'''
add.py
add
30
'''
print(add.add(10, 20))
from sub import sub
'''
sub.py
sub
-10
'''
print(sub(20, 30))
from mul import *
'''
mul.py
mul
1500
'''
print(mul(30, 50))
Apparemment
importer le nom du fichier dans la même hiérarchie
Donc, il semble que d'autres fichiers peuvent être lus comme des modules.
import add
Lorsque vous le faites, deux impressions de add.py sont exécutées. Par conséquent, il semble qu'un traitement d'écriture solide tel que l'impression soit exécuté lorsque le module est chargé. De plus, name contient add. De cette façon, il semble que le nom du fichier soit entré tel quel lorsqu'il est appelé en tant que module au lieu du point de départ de l'exécution.
nom du fichier d'importation Puisqu'elle est lue, la fonction peut être utilisée dans add.add, qui est l'espace de noms du nom de fichier.
Cette notation semble sûre car la fonction ʻadd` protège les espaces de noms les uns des autres même s'ils sont dans d'autres fichiers!
from sub import sub
Lorsque vous le faites, il semble que vous lisiez directement la fonction secondaire de sub.py. Il semble qu'il soit possible de le supprimer du module.
Cependant, il semble que la sous-fonction ne puisse pas être récupérée directement
.
Comme add.py
'''
sub.py
sub
'''
Est sortie, il semble donc que tout le contenu du sous-fichier sera exécuté au moment de from sub.
from mul import *
Vous pouvez forcer tout le contenu du fichier mul dans l'espace de noms calc_main.py en masse.
En gros ** il semble préférable de ne pas utiliser **. La raison en est qu'il provoque un comportement inattendu tel que le remplacement lors de l'utilisation du même nom que d'autres modules.
nom du fichier d'importation
Peut-être le plus pratique.
Ensuite, essayez plusieurs chargements. Je suis un arbre, comment il se comporte lorsque le même fichier est lu plusieurs fois
Pour essayer plusieurs chargements a b Une configuration simple comme c semble être plus facile.
Essayez ce qui suit.
.
├── __pycache__
├── abc
│ ├── a.py
│ ├── ab.py
│ ├── abc_main.py
│ ├── b.py
│ ├── bc.py
│ ├── c.py
│ └── ca.py
├── calc
│ ├── __pycache__
│ │ ├── add.cpython-37.pyc
│ │ ├── mul.cpython-37.pyc
│ │ └── sub.cpython-37.pyc
│ ├── add.py
│ ├── calc_main.py
│ ├── mul.py
│ └── sub.py
├── main.py
Ajout du répertoire abc. ab.py lit les fichiers a et b en tant que modules.
print('a file')
aa = 1
print('b file')
bb = 2
print('c file')
cc = 3
L'expérience commence par a, b et c.py comme décrit ci-dessus.
Essayez de lire les fichiers correspondants à partir du fichier ab.py et ainsi de suite.
ab.py
import a
import b
print('ab file')
bc.py
import b
import c
print('bc file')
ca.py
import c
import a
print('ca file')
abc_main.py
import ab
import bc
import ca
print('abc main file')
abc_main.py
Lorsque j'exécute abc_main.py, cela ressemble à ceci:
a file
b file
ab file
c file
bc file
ca file
abc main file
Il semble que les fichiers a et b soient lus en premier. Après cela, puisque les fichiers b et c sont lus, il doit être sorti en tant que fichier b, mais il est ignoré et sorti en tant que fichier c.
Apparemment, il ne se charge pas une fois qu'il est chargé.
La lecture du fichier ca ne semble pas être fâchée car les fichiers c et a ont déjà été lus. Sauf le fait qu'une fois qu'un «fichier», etc. est lu, il n'est pas lu après cela et n'est sorti qu'une seule fois.
Apparemment, le fichier est essentiellement lu une seule fois. ''
Actuellement, j'utilisais des modules sous le même répertoire tels que abc_main et calc_main.
Ensuite, est-il possible d'utiliser un module dans le répertoire inférieur suivant comme main.py?
main.py
main.py
from calc import add
'''
add.py
calc.add
5
'''
print(add.add(2, 3))
Comme mentionné ci-dessus, le module add est importé du répertoire calc. C'est le code qui fonctionne réellement.
En d'autres termes, depuis Python 3.3, vous pouvez utiliser les modules sous le répertoire. Aussi, si vous vous concentrez sur nom
calc.add
Est sortie. Par conséquent, il semble qu'il soit chargé en tant que module d'ajout de l'espace calc. Cela semble être une fonctionnalité appelée «importation d'espace de noms» depuis Python 3.3.
Cependant, cela ne fonctionne pas bien si vous procédez comme suit.
main.py
'''
from calc import add.add
^
SyntaxError: invalid syntax
'''
from calc import add.add
print(add(2, 3))
'''
AttributeError: module 'calc' has no attribute 'add'
'''
import calc
print(calc.add.add(2, 3))
Apparemment, il semble qu'il ne soit pas permis de ** affiner davantage ** en utilisant "." Dans le contenu écrit après l'importation.
De plus, il semble que ** la lecture du répertoire en tant que module ** ne soit pas autorisée.
Un package est un "** module ** qui gère tous les modules". Par exemple, j'ai créé le répertoire calc plus tôt.
.
├── calc
│ ├── __pycache__
│ │ ├── add.cpython-37.pyc
│ │ ├── mul.cpython-37.pyc
│ │ └── sub.cpython-37.pyc
│ ├── add.py
│ ├── calc_main.py
│ ├── mul.py
│ └── sub.py
En mettant ** __ init __. Py
** dans ce répertoire calc,
Vous pouvez considérer le répertoire calc lui-même comme un ** grand module **.
Bien sûr, sans __init __. Py
, le répertoire calc n'est qu'un" répertoire ".
Par conséquent, en mettant «__init __. Py», le répertoire calc lui-même est considéré comme un ** module **.
En utilisant des packages, vous pouvez gérer les fichiers dans des unités plus grandes et les structurer.
__init __. py
est la première chose à exécuter lorsque vous appelez ce module de package.
__init__.py
print(__name__)
Si vous le faites, le nom du répertoire sera affiché.
C'est parce que le répertoire est traité comme un "module" par «__init __. Py».
Essayez de réécrire le répertoire calc du package.
calc_main.py
print(__name__)
from . import add
from . import sub
from . import mul
print(add.add(2, 3))
Je vais essayer.
Pour le moment, l'exécution normale de python ne fonctionne pas.
python calc/calc_main.py
python calc_main.py
Etc
File "calc_main.py", line 3, in <module>
from . import add
ImportError: cannot import name 'add'
Erreur se produit.
python -m calc.calc_main.py
Puis
Vous pouvez exécuter calc_main.py avec calc en tant que package.
Comme vous pouvez le voir, le paquet est essentiellement un "chemin relatif" et semble maintenant être spécifié.
python calc/calc_main.py
python calc_main.py
C'est la raison pour laquelle ça ne marche pas Réécrivez avec le code suivant.
print(__name__)
print(__package__)
from . import add
from . import sub
from . import mul
print(add.add(2, 3))
python -m calc.calc_main.py
calc
__main__
calc
add.py
calc.add
sub.py
calc.sub
mul.py
calc.mul
5
python calc/calc_main.py
__main__
None
Traceback (most recent call last):
File "calc/calc_main.py", line 4, in <module>
from . import add
ImportError: cannot import name 'add'
Ce sera.
Ici, comme la différence entre eux À quel paquet appartient package? Représente (module parent) Sur celui qui ne fonctionne pas, l'attribut package est None. Par conséquent, je ne sais pas à quel package faire référence et j'obtiens une erreur. En d'autres termes, même si vous spécifiez "." Etc., ce sera "Chemin relatif à partir de quel paquet?".
pour cette raison, Si vous utilisez le package calc du répertoire principal
main.py
from calc import calc_main
print(10)
calc
calc.calc_main
calc
add.py
calc.add
sub.py
calc.sub
mul.py
calc.mul
5
10
Il sera exécuté correctement.
Par conséquent, il semble que cela fonctionne bien dans la situation où l'attribut __package__
est spécifié correctement et dans le cas d'une importation relative.
Site de référence [[Python] Importer une pierre d'achoppement](https://qiita.com/ysk24ok/items/2711295d83218c699276#package ne peut pas utiliser implicit-relative-import) J'ai essayé de résumer les modules Python Idée sur Python: différences entre les packages et les modules Python
Je vais spécifier correctement le package du module avec l'option -m.
Que dois-je faire lorsque j'utilise PyCharm? Apparemment, PyCharm se comporte différemment de Python normal. IDE semble faire une bonne supposition et se comporter différemment.
Les chemins relatifs sont utilisés lors du chargement de modules dans un package.
Dans le même package, un chemin relatif est utilisé.
calc_main.py
print(__name__)
print(__package__)
from . import add
print(add.add(2, 3))
Lorsque vous frappez le paquet d'en haut, vous pouvez le laisser tel quel. Appelez-le comme un module normal.
main.py
from calc import calc_main
print(10)
Dans PyCharm, il y a des choses comme l'exécution de la configuration de démarrage, Lorsque vous essayez d'exécuter un fichier dans un package
calc_main.py
print(__name__)
print(__package__)
from . import add
print(add.add(2, 3))
Aucun n'est généré avec package et une erreur se produit car le package n'est pas évalué. Dans ce cas
Depuis la ligne de commande
python -m calc.calc_main
Vous pouvez le donner comme.
L'exécution de la configuration de lancement de PyCharm ne fonctionne pas. C'est ennuyeux qu'il soit difficile de tester l'exécution d'un seul fichier ... Y a-t-il un moyen de bien le faire ...
https://pleiades.io/help/pycharm/content-root.html
Recommended Posts