Как импортировать класс в том же каталоге или подкаталоге?

676

У меня есть каталог, в котором хранятся все файлы .py .

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

Я хочу использовать классы из user.py и dir.py в main.py .
Как я могу импортировать эти классы Python в main.py ?
Кроме того, как я могу импортировать класс, Userесли user.py находится в подкаталоге?

bin/
    dir.py
    main.py
    usr/
        user.py
Бен Чен
источник

Ответы:

939

Python 2

Создайте пустой файл с именем __init__.pyв том же каталоге, что и файлы. Это будет означать для Python, что «можно импортировать из этого каталога».

Тогда просто делай ...

from user import User
from dir import Dir

То же самое верно, если файлы находятся в подкаталоге - также поместите его __init__.pyв подкаталог, а затем используйте обычные операторы импорта с точечной нотацией. Для каждого уровня каталога, вы должны добавить к пути импорта.

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

Итак, если каталог был назван «классы», то вы бы сделали это:

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

Python 3

То же, что и предыдущий, но префикс имени модуля с, .если не используется подкаталог:

from .user import User
from .dir import Dir
янтарный
источник
14
Если __init__.pyон не пустой, то все, что находится внутри, __init__.pyбудет доступно при импорте пакета (а вещи, не импортированные в него __init__.py, вообще не будут доступны).
Январь
23
Зачем __init__.pyнужен файл вообще? Если я положу все три файла в один и тот же каталог и запустлю main.pyего, он сможет работать importс двумя другими модулями без него. Что мне не хватает?
Мартино
30
Потому что именно так Python идентифицирует каталоги, из которых вам разрешено импортировать. Каталог скрипта, который вы запускаете, является исключением - вы всегда можете импортировать из него.
Янтарь
20
@nbro & Amber: FWIW, я думаю, что что-то неуловимое изменилось в отношении __init__.pyвозможности импорта других модулей в том же каталоге. В частности, importдругие модули в том же каталоге, что и __init__.pyсам файл, который работал в Python 2.7.8, потерпели неудачу в Python 3.4.1. Чтобы исправить это, я должен был префикс каждого из них с именем подкаталога и точки (то есть import moduleдолжен был быть изменен на import subdirectory.module). К счастью, это все еще работало в Python 2.7.8 после этого.
Мартино
4
Я могу подтвердить, что это решение больше не работает. Вы можете исправить, исправить или полностью удалить его.
Луис де Соуза
137

Я только что узнал (благодаря комментарию Мартино ), что для того, чтобы импортировать классы из файлов в одном каталоге, вы теперь должны написать в Python 3:

from .user import User
from .dir import Dir
ECP
источник
8
если я попробую это нет, я получу следующую ошибку, ValueError: Attempted relative import in non-packageно ошибка исчезнет, ​​когда я from user import User
перейду
Я использую из .fileloader import Fileloader и получаю ImportError: не могу импортировать имя 'Fileloader'
Frikster
3
@Korpel: После обсуждений в stackoverflow.com/questions/11536764/… я пришел к выводу, что независимо от того, работает ли приведенный выше импорт или нет, зависит от: [1] как называется ваш скрипт (как пакет или нет) [2] где фактический рабочий путь - это когда вы выполняете его [3], как заполняется переменная пути вашей среды выполнения
ecp
@Korpel: я заметил, что. перед именем модуля требуется только при наличии файла init .py, если нет. можно / нужно опустить.
MUG4N
40

В вашем main.py:

from user import Class

где Classимя класса, который вы хотите импортировать.

Если вы хотите вызвать метод Class, вы можете вызвать его с помощью:

Class.method

Обратите внимание, что __init__.pyв том же каталоге должен быть пустой файл.

user225312
источник
1
Что вы делаете, если модуль, который вы пытаетесь импортировать, не имеет классов? Просто сырые функции? В Python 2 все, что мне нужно было сделать, это «модуль импорта». Не работает в Python 3, как и «import .module»
Фрикстер
2
Это работает в python3 после удаления __init__.py.
Движущая сила
14

Вы можете импортировать модуль и получить доступ через его имя, если не хотите смешивать функции и классы с вашими.

import util # imports util.py

util.clean()
util.setup(4)

или вы можете импортировать функции и классы в свой код

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

вы можете использовать wildchar *, чтобы импортировать все в этом модуле в ваш код

from util import *
clean()
setup(4)
A.Zaben
источник
10

Не в Python3, __init__.pyэто больше не нужно . Если текущим каталогом консоли является каталог, в котором находится скрипт Python, все работает нормально

import user

Тем не менее, это не будет работать, если вызывается из другого каталога, который не содержит user.py.
В этом случае используйте

from . import user

Это работает, даже если вы хотите импортировать весь файл, а не просто класс оттуда.

lucidbrot
источник
2
Я использую pylint в vs-коде, и у меня были проблемы с импортом из одного и того же каталога, который всегда помечался как ошибка ( import userподчеркнут красным); изменился на относительный import ( from . import user) и линтер больше не помечал его.
rbatt
9

Чтобы было проще понять:

Шаг 1: давайте перейдем в один каталог, где все будет включено

$ cd /var/tmp

Шаг 2: теперь давайте создадим файл class1.py с именем класса Class1 с некоторым кодом

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

Шаг 3: теперь давайте создадим файл class2.py с именем класса Class2 с некоторым кодом

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

Шаг 4: теперь давайте создадим один main.py, который будет выполняться один раз, чтобы использовать Class1 и Class2 из 2 разных файлов.

$ 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

Шаг 5: Запустите программу

$ python main.py

Выход будет

[Class1 OK]: 
[Class2 OK]:
Хасан Надим
источник
4
И что произойдет, если это не сработает и main.py не сможет прочитать class1 или class2? ... что нам не хватает?
даркгейм
6

Python 3


То же самое directory.

импортировать файл:log.py

класс импорта: SampleApp().

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

или

каталог есть basic.

импортировать в файл: log.py.

класс импорта: SampleApp().

from basic import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()
Ясит Прахаршана
источник
5
from user import User 
from dir import Dir 
Димас
источник
Это сработало для меня без файла init .py для Python 2.7 и Python 3.6.
imsrgadich
1
@imsrgadich работает, пока вы запускаете python в каталоге, содержащем файлы. Это исключение. Смотрите этот комментарий
Ciprian Tomoiagă
5

Если user.py и dir.py не включают классы, то

from .user import User
from .dir import Dir

не работает. Затем вы должны импортировать как

from . import user
from . import dir
Андреас Фотеас
источник
0

Я не уверен, почему это работает, но с помощью сборки Pycharm from file_in_same_dir import class_name

IDE жаловалась на это, но, похоже, все еще работало. Я использую Python 3.7

stingMantis
источник
-2

Просто слишком кратко, создайте файл __init__.pyв каталоге классов и затем импортируйте его в свой скрипт, как показано ниже (импортировать все регистры)

from classes.myscript import *

Импортировать только выбранные классы

from classes.myscript import User
from classes.myscript import Dir
Шафик
источник
4
Импорт подстановочных знаков, как видно из этого ответа, обычно считается плохим стилем, как описано в PEP 8 .
V02460
-3

импортировать из той же директории

from . import the_file_you_want_to_import 

для импорта из подкаталога каталог должен содержать

init .py

файл, кроме вас, то файлы

из каталога импортировать ваш_файл

rojo_hlerr
источник
3
Я не думаю, что этот ответ добавляет что-то, чего не сделали другие ответы, а также не является исчерпывающим резюме других ответов. Поэтому мне интересно, почему вы написали это
lucidbrot
-3

python3

использование

from .user import User inside dir.py file

а также

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

вот так

icharis
источник
3
Этот ответ на самом деле не добавляет ничего больше, чем другой ответ, и не имеет объяснения. Можно ли как-то отредактировать свой ответ, чтобы добавить или улучшить его? Потому что в противном случае, он должен быть опущен, как этот ответ был или удален полностью.
Das_Geek