Ik gebruik Python 3.7.1 op macOS Mojave versie 10.14.1
Dit is mijn directorystructuur:
man/
Mans/
man1.py
MansTest/
SoftLib/
Soft/
SoftWork/
manModules.py
Unittests/
man1test.py
man1.py
bevat de volgende import-instructie, die ik niet wil wijzigen:
from Soft.SoftWork.manModules import *
man1test.py
bevat de volgende import-instructies:
from ...MansTest.SoftLib import Soft
from ...Mans import man1
Ik heb de tweede importnodig in man1test.py
omdat man1test.py
toegang nodig heeft tot een functie in man1.py
.
Mijn grondgedachte achter de eerste import (Soft) was om de bovengenoemde import-instructie in man1.py
te vergemakkelijken.
In tegenstelling tot mijn verwachting geeft het importstatement in man1.py
echter aanleiding tot:
ModuleNotFoundError: No module named 'Soft'
wanneer ik ren
python3 -m man.MansTest.Unittests.man1test
uit een map boven man/.
Is er een manier om deze fout op te lossen zonder de import-instructie in man1.py
ente wijzigen zonder iets toe te voegen aan sys .pad?
Bewerken: python3 -m man.ManTest.Unittests.man1test
van de oorspronkelijke versie van de vraag gewijzigd in python3 -m man.MansTest.Unittests.man1test
Antwoord 1, autoriteit 100%
EERST, als u toegang wilt hebben tot man1.pyvanuit man1test.pyEN manModules.pyvan man1.py, moet u uw bestanden correct instellen als pakketten en modules.
Pakketten zijn een manier om de modulenaamruimte van Python te structureren door gebruik te maken van
“gestippelde modulenamen”. De modulenaamA.B
duidt bijvoorbeeld a . aan
submodule met de naamB
in een pakket met de naamA
.…
Bij het importeren van het pakket zoekt Python door de mappen op
sys.path
op zoek naar de submap van het pakket.De
__init__.py
bestanden zijn vereist om Python de . te laten behandelen
directory’s die pakketten bevatten; dit wordt gedaan om te voorkomen
mappen met een algemene naam, zoalsstring
, van onbedoeld
geldige modules verbergen die later in het zoekpad van de module voorkomen.
Je moet het ongeveer als volgt instellen:
man
|- __init__.py
|- Mans
|- __init__.py
|- man1.py
|- MansTest
|- __init.__.py
|- SoftLib
|- Soft
|- __init__.py
|- SoftWork
|- __init__.py
|- manModules.py
|- Unittests
|- __init__.py
|- man1test.py
TWEEDE, voor de “ModuleNotFoundError: No module named 'Soft'
” fout veroorzaakt door from ...Mans import man1
in man1test.py, de gedocumenteerde oplossing daarvoor is om man1.pytoe te voegen aan sys.path
aangezien Mansbuiten het MansTestpakket. Zie Het modulezoekpaduit de Python-documentatie . Maar als u sys.path
niet rechtstreeks wilt wijzigen, kunt u ook PYTHONPATH
wijzigen:
sys.path
wordt geïnitialiseerd vanaf deze locaties:
- De map met het invoerscript (of de huidige map als er geen bestand is opgegeven).
PYTHONPATH
(een lijst met directorynamen, met dezelfde syntaxis als de shellvariabelePATH
).- De installatie-afhankelijke standaard.
THIRD, voor from ...MansTest.SoftLib import Soft
waarvan u zei “was om de bovengenoemde importinstructie in man1.py“, zo werkt import nu. Als u Soft.SoftLibin man1.pywilt importeren, moet u man1.pyinstellen om Soft.SoftLiben importeer het daar direct.
Dat gezegd hebbende, hier is hoe ik het werkend heb gekregen.
man1.py:
from Soft.SoftWork.manModules import *
# no change to import statement but need to add Soft to PYTHONPATH
def foo():
print("called foo in man1.py")
print("foo call module1 from manModules: " + module1())
man1test.py
# no need for "from ...MansTest.SoftLib import Soft" to facilitate importing..
from ...Mans import man1
man1.foo()
MANMODULES.PY
def module1():
return "module1 in manModules"
Terminal-uitgang:
$ python3 -m man.MansTest.Unittests.man1test
Traceback (most recent call last):
...
from ...Mans import man1
File "/temp/man/Mans/man1.py", line 2, in <module>
from Soft.SoftWork.manModules import *
ModuleNotFoundError: No module named 'Soft'
$ PYTHONPATH=$PYTHONPATH:/temp/man/MansTest/SoftLib
$ export PYTHONPATH
$ echo $PYTHONPATH
:/temp/man/MansTest/SoftLib
$ python3 -m man.MansTest.Unittests.man1test
called foo in man1.py
foo called module1 from manModules: module1 in manModules
Als een suggestie, misschien denk je het doel van die Softlib -bestanden. Is het een soort van “bridge” tussen Man 1. Py en man1test.py ? De manier waarop uw bestanden nu worden ingesteld, denk ik niet dat het gaat werken terwijl u verwacht dat het is. Het is ook een beetje verwarrend voor de Code-Under-Test (Man 1. Py ) om dingen uit onder de testmap te importeren (MANSTEST ).
Antwoord 2
Voor mij wanneer ik een bestand heb gemaakt en het als Python-bestand heeft opgeslagen, kreeg ik deze fout tijdens het importeren.
Ik moest een bestandsnaam maken met het type “.py”, zoals bestandsnaam.py en vervolgens opslaan als een Python-bestand.
Post proberen om het bestand voor mij te importeren.