web-dev-qa-db-fra.com

Pourquoi les modules Python n'importent-ils pas parfois leurs sous-modules?

J'ai remarqué quelque chose d'étrange aujourd'hui que j'aimerais expliquer. Je ne savais pas à 100% comment formuler cela comme une question, alors Google est hors de question. Le module de journalisation n'a pas accès au module logging.handlers pour une raison étrange. Essayez-le vous-même si vous ne me croyez pas:

>>> import logging
>>> logging.handlers
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'handlers'
>>> import logging.handlers
>>> logging.handlers
<module 'logging.handlers' from '/usr/lib/python2.6/logging/handlers.pyc'>

Quelqu'un peut-il expliquer pourquoi cela se produit?

72
chriscauley

En Python, les modules doivent être importés avant d'être accessibles. import logging importe uniquement le module de journalisation. Il se trouve que logging est un package avec des sous-modules, mais ces sous-modules ne sont toujours pas chargés automatiquement. Vous devez donc importer explicitement logging.handlers avant de pouvoir y accéder.

Si vous vous demandez pourquoi il semble parfois que vous n'ayez pas besoin de ces importations supplémentaires: certains packages importent tout ou partie de leurs sous-modules lorsqu'ils sont importés - simplement en effectuant ces importations dans leur __init__.py des dossiers. Dans d'autres cas, il se peut que quelque chose d'autre que vous importiez, également importé logging.handlers. Peu importe quel morceau de code importe; tant que quelque chose dans votre processus importe logging.handlers avant d'y accéder, il sera là. Et parfois, un module qui ressemble à un paquet n'en est vraiment pas un, comme os et os.path. os n'est pas un package, il importe simplement l'autre module correct (pour votre plateforme) et l'appelle path, juste pour que vous puissiez y accéder en tant que os.path.

97
Thomas Wouters

Je suis également nouveau sur python et après avoir beaucoup de pratique maintenant je peux faire la différence entre, package (dossier), module (.py), classes, variables ... etc ...

si vous voulez que l'un de vos dossiers soit python - Il doit contenir __init__.py fichier même un fichier vide fera l'affaire !!!

et comme Thomas l'a dit, vous pouvez importer un module supplémentaire dans __init__.py si tu veux !!! mais les modules/packages ne sont accessibles qu'après leur importation ...

si vous voulez tout importer d'un module, vous pouvez utiliser

from logging import *

vous pouvez également accéder au module des gestionnaires comme ci-dessous,

from logging import handlers
print dir(handlers)
3
shahjapan

J'ai récemment fait face à la même situation étrange. Donc, je parie que vous avez supprimé une importation de bibliothèque tierce. Cette bibliothèque supprimée contenait from logging import handlers ou from logging import * et vous a fourni handlers. Et dans un autre script, vous avez eu quelque chose comme import logging et vient d'utiliser logging.handlers et vous avez pensé que c'est comme ça que les choses fonctionnent comme moi.

1
Alexey

Thomas Wouters a très bien répondu à cette question, mais hélas, je n'ai trouvé cette question qu'après avoir trouvé la réponse dans la documentation d'origine. À cette fin, j'ai pensé que j'ajouterais à cela dans l'espoir que cela se rapproche du haut du moteur de recherche à l'avenir.

[~ # ~] question [~ # ~]

Pourquoi l'erreur: ' AttributeError: module' module_name 'n'a pas d'attribut' sub_module_name 'apparaît même si mon éditeur (par exemple Visual Code) complète automatiquement le nom du sous-module:

 import module_name
 module_name.sub_module_name(parameter)

[~ # ~] répondre [~ # ~]

Votre éditeur base sa saisie semi-automatique sur la structure de fichiers de votre projet et non sur Python. Les sous-modules ne sont pas importés "automatiquement" lorsque vous importez un module. Référence Documentation Python pour plus de détails sur la façon d'importer "automatiquement" des sous-modules lors de l'utilisation

 import module_name

La principale contribution de cette réponse est l'ajout d'AttributeError lors de la tentative d'importation d'un "module" ou d'un "package"

J'espère que cela aide quelqu'un!

1
Underflow