Jak zaimportować klasę w tym samym katalogu lub podkatalogu?


675

Mam katalog, w którym przechowywane są wszystkie pliki .py .

bin/
   main.py
   user.py # where class User resides
   dir.py # where class Dir resides

Chcę użyć klas z user.py i dir.py w main.py .
Jak mogę zaimportować te klasy Python do main.py ?
Ponadto, jak mogę zaimportować klasę, Userjeśli user.py znajduje się w podkatalogu?

bin/
    dir.py
    main.py
    usr/
        user.py

Zobacz także odpowiedzi w Pythonie: importuj plik z podkatalogu .
Trilarion

Odpowiedzi:


938

Python 2

Utwórz pusty plik wywoływany __init__.pyw tym samym katalogu co pliki. Będzie to oznaczać dla Pythona, że ​​„można importować z tego katalogu”.

Więc po prostu zrób ...

from user import User
from dir import Dir

To samo dotyczy praw, jeśli pliki znajdują się w podkatalogu - umieść również __init__.pyw podkatalogu, a następnie użyj zwykłych instrukcji importu, z notacją kropkową. Dla każdego poziomu katalogu należy dodać do ścieżki importu.

bin/
    main.py
    classes/
        user.py
        dir.py

Więc jeśli katalog zostałby nazwany „klasami”, zrobiłbyś to:

from classes.user import User
from classes.dir import Dir

Python 3

Taki sam jak poprzedni, ale poprzedź nazwę modułu przedrostkiem, .jeśli nie używa podkatalogu:

from .user import User
from .dir import Dir

14
Jeśli nie__init__.py jest pusty, to cokolwiek jest, będzie dostępne po zaimportowaniu pakietu (a rzeczy, do których nie zaimportowano , nie będą w ogóle dostępne). __init__.py__init__.py
Amber

23
Dlaczego __init__.pyw ogóle potrzebny jest plik? Jeśli włożę wszystkie trzy pliki do tego samego katalogu i uruchomię main.py, będzie to możliwe importz dwóch pozostałych modułów bez niego. czego mi brakuje?
martineau,

30
Ponieważ w ten sposób Python identyfikuje katalogi, z których możesz importować. Katalog uruchomionego skryptu jest wyjątkiem - zawsze możesz z niego importować.
Amber

20
@nbro & Amber: FWIW, myślę, że coś subtelnego zmieniło się w odniesieniu do __init__.pymożliwości importowania innych modułów w tym samym katalogu. W szczególności imports innych modułów w tym samym katalogu, co __init__.pysam plik, który działał w Pythonie 2.7.8, zawiódł w Pythonie 3.4.1. Aby to naprawić, musiałem poprzedzić każdą z nich nazwą podkatalogu i kropką (tj. import moduleMusiałem zmienić na import subdirectory.module). Na szczęście po wykonaniu tej czynności nadal działało w Pythonie 2.7.8.
martineau

4
Mogę potwierdzić, że to rozwiązanie nie działa. Możesz go poprawić, zmienić lub całkowicie usunąć.
Luís de Sousa

137

Właśnie dowiedziałem się (dzięki komentarzowi Martineau ), że aby zaimportować klasy z plików w tym samym katalogu, piszesz teraz w Pythonie 3:

from .user import User
from .dir import Dir

8
jeśli spróbuję tego nie, ValueError: Attempted relative import in non-packagefrom user import User
pojawi

Używam z .fileloader importu Fileloader i otrzymuję ImportError: nie mogę zaimportować nazwy „Fileloader”
Frikster

3
@Korpel: Po dyskusjach na stackoverflow.com/questions/11536764 /... zdaję sobie sprawę, że niezależnie od tego, czy powyższy import działa, czy nie, zależy od: [1] jak wywoływany jest twój skrypt (jako pakiet czy nie) [2] gdzie rzeczywista ścieżka praca jest, kiedy go wykonać [3], jak zmienna ścieżka środowisku roboczym jest pusta
ECP

@Korpel: Zauważyłem, że. przed nazwa modułu jest wymagana tylko wtedy, gdy obecny jest plik init .py, jeśli nie. można / należy pominąć.
MUG4N

39

W twoim main.py:

from user import Class

gdzie Class jest nazwa klasy, którą chcesz zaimportować.

Jeśli chcesz wywołać metodę Class, możesz wywołać ją za pomocą:

Class.method

Pamiętaj, że __init__.pyw tym samym katalogu powinien znajdować się pusty plik.


1
Co robisz, jeśli moduł, który próbujesz zaimportować, nie ma klas? Tylko surowe funkcje? W Pythonie 2 wszystko, co musiałem zrobić, to „moduł importu”. Nie działa w Pythonie 3,
podobnie

2
Działa to w python3 po usunięciu pliku __init__.py.
Engineforce

13

Możesz zaimportować moduł i uzyskać dostęp poprzez jego nazwę, jeśli nie chcesz mieszać funkcji i klas z twoimi

import util # imports util.py

util.clean()
util.setup(4)

lub możesz zaimportować funkcje i klasy do swojego kodu

from util import clean, setup
clean()
setup(4)

możesz użyć wildchar *, aby zaimportować wszystko z tego modułu do swojego kodu

from util import *
clean()
setup(4)

10

W python3 nie__init__.py jest już konieczne . Jeśli bieżącym katalogiem konsoli jest katalog, w którym znajduje się skrypt Pythona, wszystko działa poprawnie

import user

Nie zadziała to jednak, jeśli zostanie wywołany z innego katalogu, który nie zawiera user.py.
W takim przypadku użyj

from . import user

Działa to nawet, jeśli chcesz zaimportować cały plik zamiast tylko stamtąd stamtąd.


2
Korzystam z pylinta w kodzie vs i miałem problem z importem tego samego katalogu zawsze oznaczonym jako błąd ( import userpodkreślono na czerwono); zmieniono na względny import ( from . import user) i linijka już go nie oflagowała.
rbatt

9

Aby ułatwić zrozumienie:

Krok 1: przejdźmy do jednego katalogu, w którym wszystkie zostaną uwzględnione

$ cd /var/tmp

Krok 2: Teraz możemy utworzyć plik class1.py, który ma nazwę klasy Class1 z pewnym kodem

$ cat > class1.py <<\EOF
class Class1:
    OKBLUE = '\033[94m'
    ENDC = '\033[0m'
    OK = OKBLUE + "[Class1 OK]: " + ENDC
EOF

Krok 3: Teraz stwórzmy plik class2.py, który ma nazwę klasy Class2 z pewnym kodem

$ cat > class2.py <<\EOF
class Class2:
    OKBLUE = '\033[94m'
    ENDC = '\033[0m'
    OK = OKBLUE + "[Class2 OK]: " + ENDC
EOF

Krok 4: teraz pozwala stworzyć jeden main.py, który zostanie wykonany raz, aby użyć Class1 i Class2 z 2 różnych plików

$ cat > main.py <<\EOF
"""this is how we are actually calling class1.py and  from that file loading Class1"""
from class1 import Class1 
"""this is how we are actually calling class2.py and  from that file loading Class2"""
from class2 import Class2

print Class1.OK
print Class2.OK
EOF

Krok 5: Uruchom program

$ python main.py

Wynik byłby

[Class1 OK]: 
[Class2 OK]:

4
A co się stanie, jeśli to nie zadziała, a main.py nie może odczytać klasy 1 lub klasy 2? ... czego nam brakuje?
darkgaze

6

Python 3


Podobnie directory .

importować plik:log.py

Klasa import: SampleApp().

import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()

lub

katalog jest basic .

import do pliku: log.py .

Klasa import: SampleApp().

from basic import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()


5

Jeśli user.py i dir.py nie obejmują klas, to

from .user import User
from .dir import Dir

nie działa. Następnie należy zaimportować jako

from . import user
from . import dir

0

Nie jestem pewien, dlaczego to działa, ale przy użyciu kompilacji Pycharm from file_in_same_dir import class_name

IDE narzekało na to, ale wygląda na to, że nadal działało. Używam Python 3.7


-2

Po prostu zbyt krótko, Utwórz plik __init__.pyto katalog klas, a następnie zaimportuj go do skryptu w następujący sposób (Importuj całą wielkość liter)

from classes.myscript import *

Importuj tylko wybrane klasy

from classes.myscript import User
from classes.myscript import Dir

4
Import symboli wieloznacznych, jak widać w tej odpowiedzi, jest ogólnie uważany za zły styl, jak opisano w PEP 8 .
V02460

-3

importować z tego samego katalogu

from . import the_file_you_want_to_import 

aby zaimportować z podkatalogu, katalog powinien zawierać

init .py

wtedy plik inny niż ty

z katalogu zaimportuj swój plik


3
Nie sądzę, aby ta odpowiedź dodała coś, czego nie udzieliły inne odpowiedzi, a także nie jest wyczerpującym podsumowaniem innych odpowiedzi. Zastanawiam się więc, dlaczego to napisałeś
lucidbrot

-3

Python3

posługiwać się

from .user import User inside dir.py file

i

use from class.dir import Dir inside main.py
or from class.usr import User inside main.py

lubię to


3
Ta odpowiedź tak naprawdę nie dodaje niczego więcej niż inna odpowiedź, którą już zrobiono, i nie ma wyjaśnienia. Czy istnieje sposób na edycję odpowiedzi w celu dodania lub ulepszenia? Bo w przeciwnym razie należy zanegować, tak jakby ta odpowiedź została lub została całkowicie usunięta.
Das_Geek,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.