C'est la première fois que je m'assieds vraiment et que j'essaie python 3, et que je semble échouer lamentablement. J'ai les deux fichiers suivants:
config.py a quelques fonctions définies ainsi que quelques variables. Je l'ai réduit à ce qui suit:
Cependant, j'obtiens l'erreur suivante:
ModuleNotFoundError: No module named 'config'
Je suis conscient que la convention py3 consiste à utiliser des importations absolues:
from . import config
Cependant, cela conduit à l'erreur suivante:
ImportError: cannot import name 'config'
Donc, je ne sais pas quoi faire ici ... Toute aide est grandement appréciée. :)
Comme indiqué dans les commentaires du message d'origine, cela semblait être un problème avec l'interprète python que j'utilisais pour une raison quelconque, et pas un problème avec les scripts python. Je suis passé du paquet WinPython au lot officiel python 3.6 de python.org et tout a bien fonctionné. Merci à tous pour l'aide :)
TL; DR: vous ne pouvez pas importer de données relatives à partir du fichier exécuter car le module __main__
ne fait pas partie d'un paquet.
Importations absolues - Importer quelque chose disponible sur sys.path
Importations relatives - importer quelque chose par rapport au module actuel, doit faire partie d'un package
Si vous utilisez les deux variantes exactement de la même manière, l'une d'entre elles devrait fonctionner. Quoi qu'il en soit, voici un exemple qui devrait vous aider à comprendre ce qui se passe, ajoutons un autre fichier main.py
avec la structure de répertoires globale comme ceci:
.
./main.py
./ryan/__init__.py
./ryan/config.py
./ryan/test.py
Et mettons à jour test.py pour voir ce qui se passe:
# config.py
debug = True
# test.py
print(__name__)
try:
# Trying to find module in the parent package
from . import config
print(config.debug)
del config
except ImportError:
print('Relative import failed')
try:
# Trying to find module on sys.path
import config
print(config.debug)
except ModuleNotFoundError:
print('Absolute import failed')
# main.py
import ryan.test
Lançons d'abord test.py:
$ python ryan/test.py
__main__
Relative import failed
True
Ici "test" est le module __main__
et ne sait rien de l'appartenance à un paquet. Cependant, import config
devrait fonctionner, car le dossier ryan
sera ajouté à sys.path.
Lançons main.py à la place:
$ python main.py
ryan.test
True
Absolute import failed
Et ici, le test se trouve à l'intérieur du paquet "ryan" et peut effectuer des importations relatives. import config
échoue car les importations relatives implicites ne sont pas autorisées dans Python 3.
J'espère que cela a aidé.
P.S .: si vous vous en tenez à Python 3, les fichiers __init__.py
ne sont plus nécessaires.
Je l'ai compris. Très frustrant, surtout venant de python2.
Vous devez ajouter un .
au module, qu'il soit relatif ou absolu.
J'ai créé la configuration du répertoire comme suit.
/main.py
--/lib
--/__init__.py
--/mody.py
--/modx.py
modx.py
def does_something():
return "I gave you this string."
mody.py
from modx import does_something
def loaded():
string = does_something()
print(string)
main.py
from lib import mody
mody.loaded()
quand j'exécute main, c'est ce qui se passe
$ python main.py
Traceback (most recent call last):
File "main.py", line 2, in <module>
from lib import mody
File "/mnt/c/Users/Austin/Dropbox/Source/Python/virtualenviron/mock/package/lib/mody.py", line 1, in <module>
from modx import does_something
ImportError: No module named 'modx'
J'ai couru 2to3, et la sortie principale était-ce
RefactoringTool: Refactored lib/mody.py
--- lib/mody.py (original)
+++ lib/mody.py (refactored)
@@ -1,4 +1,4 @@
-from modx import does_something
+from .modx import does_something
def loaded():
string = does_something()
RefactoringTool: Files that need to be modified:
RefactoringTool: lib/modx.py
RefactoringTool: lib/mody.py
Je devais modifier la déclaration d'importation de mody.py pour y remédier
try:
from modx import does_something
except ImportError:
from .modx import does_something
def loaded():
string = does_something()
print(string)
Ensuite, j'ai de nouveau exécuté main.py et obtenu le résultat attendu
$ python main.py
I gave you this string.
Enfin, juste pour le nettoyer et le rendre portable entre 2 et 3.
from __future__ import absolute_import
from .modx import does_something
La définition de PYTHONPATH peut également aider à résoudre ce problème.
Voici comment cela peut être fait sous Windows
set PYTHONPATH=.
Essayé votre exemple
from . import config
a obtenu l'erreur SystemError suivante:
/usr/bin/python3.4 test.py
Traceback (dernier appel passé):
Fichier "test.py", ligne 1, dans
de . importation config
SystemError: le module parent '' n'est pas chargé, impossible d'effectuer l'importation relative
Cela fonctionnera pour moi:
import config
print('debug=%s'%config.debug)
>>>debug=True
Testé avec Python: 3.4.2 - PyCharm 2016.3.2
A côté de cela, PyCharm vous propose d'importer ce nom .
Vous devez cliquer sur config
et une icône d’aide apparaît.
Vous pouvez simplement ajouter le fichier suivant à votre répertoire de tests, puis python l'exécutera avant les tests
__init__.py file
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
Vous devez ajouter le chemin du module à PYTHONPATH
:
export PYTHONPATH="${PYTHONPATH}:/path/to/your/module/"
Cet exemple fonctionne sur Python 3.6.
Je suggère d’aller dans Run -> Edit Configurations
dans PyCharm, d’y supprimer toutes les entrées et d’essayer de réexécuter le code dans PyCharm.
Si cela ne fonctionne pas, vérifiez votre interpréteur de projet (Paramètres -> Interprète de projet) et exécutez les paramètres de configuration par défaut (Exécuter -> Modifier les configurations ...).
Déclarez la bonne sys.path liste avant d'appeler le module:
import os, sys
#'/home/user/example/parent/child'
current_path = os.path.abspath('.')
#'/home/user/example/parent'
parent_path = os.path.dirname(current_path)
sys.path.append(parent_path)
os.environ.setdefault('Django_SETTINGS_MODULE', 'child.settings')