Dit is de eerste keer dat ik echt ben gaan zitten en python 3 heb geprobeerd, en het lijkt jammerlijk te falen. Ik heb de volgende twee bestanden:
- test.py
- config.py
config.py heeft een paar functies die erin zijn gedefinieerd, evenals een paar variabelen. Ik heb het teruggebracht tot het volgende:
config.py
debug = True
test.py
import config
print (config.debug)
Ik heb ook een __init__.py
Ik krijg echter de volgende foutmelding:
ModuleNotFoundError: No module named 'config'
Ik ben me ervan bewust dat de py3-conventie is om absolute imports te gebruiken:
from . import config
Dit leidt echter tot de volgende fout:
ImportError: cannot import name 'config'
Dus ik weet niet wat ik hier moet doen… Alle hulp wordt zeer op prijs gesteld. 🙂
Antwoord 1, autoriteit 100%
TL;DR: u kunt geen relatieve import uitvoeren vanuit het bestand dat u uitvoert aangezien de module __main__
geen onderdeel is van een pakket .
Absolute import – importeer iets dat beschikbaar is op sys.path
Relatieve import – importeer iets relatief aan de huidige module, moet deel uitmaken van een pakket
Als je beide varianten op precies dezelfde manier gebruikt, zou een van beide moeten werken. Hier is een voorbeeld dat u zou moeten helpen begrijpen wat er aan de hand is. Laten we nog een main.py
-bestand toevoegen met de algemene directorystructuur als volgt:
.
./main.py
./ryan/__init__.py
./ryan/config.py
./ryan/test.py
En laten we test.py
updaten om te zien wat er aan de hand is:
# 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
Laten we eerst test.py
uitvoeren:
$ python ryan/test.py
__main__
Relative import failed
True
Hier "testen" is de __main__
module en weet niets over het behoren tot een pakket. import config
zou echter moeten werken, aangezien de map ryan
wordt toegevoegd aan sys.path
.
Laten we in plaats daarvan main.py
uitvoeren:
$ python main.py
ryan.test
True
Absolute import failed
En hier zit de test in de "ryan" pakket en kan relatieve importen uitvoeren. import config
mislukt omdat impliciete relatieve import niet is toegestaan in Python 3.
Hopelijk heeft dit geholpen.
P.S.: Als je bij Python 3 blijft, heb je geen __init__.py
-bestanden meer nodig.
Antwoord 2, autoriteit 35%
Ik heb het door. Zeer frustrerend, vooral afkomstig van python2.
Je moet een .
toevoegen aan de module, ongeacht of deze relatief of absoluut is.
Ik heb de directory-instellingen als volgt gemaakt.
/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()
wanneer ik main uitvoer, gebeurt dit
$ 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'
Ik heb 2 op 3 uitgevoerd, en de kernuitvoer was dit
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
Ik moest het importstatement van mody.py aanpassen om het te repareren
try:
from modx import does_something
except ImportError:
from .modx import does_something
def loaded():
string = does_something()
print(string)
Toen heb ik main.py opnieuw uitgevoerd en kreeg de verwachte output
$ python main.py
I gave you this string.
Ten slotte, gewoon om het op te ruimen en het draagbaar te maken tussen 2 en 3.
from __future__ import absolute_import
from .modx import does_something
Antwoord 3, autoriteit 30%
Je moet het pad van je project toevoegen aan PYTHONPATH
en ervoor zorgen dat je absolute imports gebruikt.
Voor UNIX (Linux, OSX, …)
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
Voor Windows
set PYTHONPATH=%PYTHONPATH%;C:\path\to\your\project\
Absolute import
Ervan uitgaande dat we de volgende projectstructuur hebben,
L-- myproject
+-- mypackage
¦ +-- a.py
L-- anotherpackage
+-- b.py
+-- c.py
L-- mysubpackage
L-- d.py
zorg er wel voor dat u naar elke import verwijst vanaf de hoofdmap van het project. Bijvoorbeeld,
# in module a.py
import anotherpackage.mysubpackage.d
# in module b
import anotherpackage.c
import mypackage.a
Raadpleeg voor een uitgebreidere uitleg het artikel Hoe ModuleNotFoundError op te lossen en ImportError
Antwoord 4, autoriteit 21%
Het instellen van PYTHONPATH kan ook helpen bij dit probleem.
Hier is hoe het kan worden gedaan op Windows
set PYTHONPATH=.
Antwoord 5, autoriteit 8%
Je kunt eenvoudig het volgende bestand toevoegen aan je testdirectory, en dan zal python het uitvoeren voor de tests
__init__.py file
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
Antwoord 6, autoriteit 6%
Uw voorbeeld geprobeerd
from . import config
kreeg de volgende SystemError:
/usr/bin/python3.4 test.py
Traceback (meest recente oproep als laatste):
Bestand “test.py”, regel 1, in
van . configuratie importeren
SystemError: Parent module ” niet geladen, kan relatieve import niet uitvoeren
Dit zal voor mij werken:
import config
print('debug=%s'%config.debug)
>>>debug=True
Getest met Python:3.4.2 – PyCharm 2016.3.2
Daarnaast biedt PyCharm u aan om deze naam te importeren.
U moet op config
klikken en er verschijnt een helppictogram.
Antwoord 7, autoriteit 4%
Stel de omgevingsvariabele PYTHONPATH
in in de hoofdmap van het project.
Gezien UNIX-achtig:
export PYTHONPATH=.
Antwoord 8, autoriteit 3%
Declareer de juiste sys.path lijst voordat je module oproept:
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')
Antwoord 9, autoriteit 2%
Dit voorbeeld werkt op Python 3.6.
Ik raad aan om naar Run -> Edit Configurations
in PyCharm, verwijder alle vermeldingen daar en probeer de code opnieuw door PyCharm te laten lopen.
Als dat niet werkt, controleer dan uw projectinterpreter (Instellingen -> Projectinterpreter) en voer de standaardinstellingen van de configuratie uit (Uitvoeren -> Configuraties bewerken…).
Antwoord 10, autoriteit 2%
Probeer
from . import config
Wat dat doet, is importeren vanuit hetzelfde mapniveau. Als u rechtstreeks probeert te importeren, wordt ervan uitgegaan dat het een ondergeschikte is
Antwoord 11
Zoals werd vermeld in de opmerkingen bij het oorspronkelijke bericht, leek dit een probleem te zijn met de python-interpreter die ik om welke reden dan ook gebruikte, en niet iets mis met de python-scripts. Ik schakelde over van de WinPython-bundel naar de officiële python 3.6 van python.org en het werkte prima. bedankt voor de hulp iedereen 🙂
Antwoord 12
Als je python 3+ gebruikt, probeer dan onderstaande regels toe te voegen
import os, sys
dir_path = os.path.dirname(os.path.realpath(__file__))
parent_dir_path = os.path.abspath(os.path.join(dir_path, os.pardir))
sys.path.insert(0, parent_dir_path)
Antwoord 13
Voor mij werkte het toevoegen van de huidige directory.
De volgende structuur gebruiken:
L-- myproject
+-- a.py
L-- b.py
a.py:
from b import some_object
# returns ModuleNotFound error
from myproject.b import some_object
# works
Antwoord 14
pip install config
Blijkbaar kan ik niet zomaar 18 tekens typen, vandaar deze tekst!