Een bestand importeren uit een submap?

Ik heb een bestand met de naam tester.py, te vinden op /project.

/projectheeft een submap met de naam lib, met een bestand met de naam boxtime.py:

/project/tester.py
/project/lib/BoxTime.py

Ik wil BoxTimeimporteren uit tester. Ik heb dit geprobeerd:

import lib.BoxTime

Wat resulteerde:

Traceback (most recent call last):
  File "./tester.py", line 3, in <module>
    import lib.BoxTime
ImportError: No module named lib.BoxTime

Ideeën voor het importeren van BoxTimeuit de submap?

BEWERKEN

De __init__.pywas het probleem, maar vergeet niet naar BoxTimete verwijzen als lib.BoxTime, of gebruik:

import lib.BoxTime as BT
...
BT.bt_function()

Antwoord 1, autoriteit 100%

Bekijk de Pakketdocumentatie (paragraaf 6.4).

Kortom, u moet een leeg bestand met de naam

. plaatsen

__init__.py

in de libdirectory.


Antwoord 2, autoriteit 32%

  • Maak een submap met de naam lib.
  • Maak een leeg bestand met de naam lib\__init__.py.
  • Schrijf in lib\BoxTime.pyeen functie foo()als volgt:

    def foo():
        print "foo!"
    
  • In uw klantcode in de directory boven libschrijft u:

    from lib import BoxTime
    BoxTime.foo()
    
  • Voer uw klantcode uit. Je krijgt:

    foo!
    

Veel later — in linux zou het er zo uitzien:

% cd ~/tmp
% mkdir lib
% touch lib/__init__.py
% cat > lib/BoxTime.py << EOF
heredoc> def foo():
heredoc>     print "foo!"
heredoc> EOF
% tree lib
lib
├── BoxTime.py
└── __init__.py
0 directories, 2 files
% python 
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from lib import BoxTime
>>> BoxTime.foo()
foo!

Antwoord 3, autoriteit 13%

Je kunt proberen het in te voegen in sys.path:

sys.path.insert(0, './lib')
import BoxTime

Antwoord 4, autoriteit 7%

Ik schrijf dit op omdat iedereen lijkt te suggereren dat je een libdirectory moet maken.

U hoeft uw submap libniet een naam te geven. Je kunt het anythingnoemen, op voorwaarde dat je er een __init__.pyin plaatst.

Je kunt dat doen door de volgende opdracht in een linux-shell in te voeren:

$ touch anything/__init__.py 

Dus nu heb je deze structuur:

$ ls anything/
__init__.py
mylib.py
$ ls
main.py

Vervolgens kunt u mylibals volgt in main.pyimporteren:

from anything import mylib 
mylib.myfun()

Je kunt ook functies en klassen als volgt importeren:

from anything.mylib import MyClass
from anything.mylib import myfun
instance = MyClass()
result = myfun()

Elke variabele functie of klasse die u in __init__.pyplaatst, is ook toegankelijk:

import anything
print(anything.myvar)

Of zoals dit:

from anything import myvar
print(myvar)

Antwoord 5, autoriteit 3%

Bevat uw lib-directory een bestand __init__.py?

Python gebruikt __init__.pyom te bepalen of een directory een module is.


Antwoord 6, autoriteit 3%

Probeer import .lib.BoxTime. Lees voor meer informatie over relatieve import in PEP 328.


Antwoord 7, autoriteit 3%

Volledig voorbeeld inbegrepen

Dit dekt in principe alle gevallen (zorg ervoor dat u __init__.pyin relative/path/to/your/lib/folder heeft):

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/your/lib/folder")
import someFileNameWhichIsInTheFolder
...
somefile.foo()

Voorbeeld:

Je hebt in je projectmap:

/root/myproject/app.py

Je hebt in een andere projectmap:

/root/anotherproject/utils.py
/root/anotherproject/__init__.py

Je wilt /root/anotherproject/utils.pygebruiken en de foo-functie aanroepen die erin zit.

Dus je schrijft in app.py:

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../anotherproject")
import utils
utils.foo()

Antwoord 8

Maak een leeg bestand __init__.pyin submap /lib.
En voeg toe aan het begin van de hoofdcode

from __future__ import absolute_import 

dan

import lib.BoxTime as BT
...
BT.bt_function()

of beter

from lib.BoxTime import bt_function
...
bt_function()

Antwoord 9

Gewoon een aanvulling op deze antwoorden.

Als u allebestanden uit alle submappenwilt importeren, kunt u dit toevoegen aan de hoofdmap van uw bestand.

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

En dan kunt u eenvoudig bestanden uit de submappen importeren alsof deze bestanden zich in de huidige map bevinden.

Werkvoorbeeld

Als ik de volgende map met submappen in mijn project heb…

.
├── a.py
├── b.py
├── c.py
├── subdirectory_a
│   ├── d.py
│   └── e.py
├── subdirectory_b
│   └── f.py
├── subdirectory_c
│   └── g.py
└── subdirectory_d
    └── h.py

Ik kan de volgende code in mijn a.py-bestand

. plaatsen

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])
# And then you can import files just as if these files are inside the current directory
import b
import c
import d
import e
import f
import g
import h

Met andere woorden, deze code abstraheert uit welke map het bestand komt.


Antwoord 10

/project/tester.py

/project/lib/BoxTime.py

maak een leeg bestand __init__.pylangs de regel totdat u het bestand bereikt

/project/lib/somefolder/BoxTime.py

#lib— needs heeft twee items: een __init__.pyen een map met de naam somefolder
#somefolderheeft twee items boxtime.pyen __init__.py


Antwoord 11

probeer dit:

from lib import BoxTime

Other episodes