Як імпортувати клас у межах одного каталогу чи підкаталога?


675

У мене є каталог, в якому зберігаються всі .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

Дивіться також відповіді в Python: імпортуйте файл із підкаталогу .
Триларіон

Відповіді:


938

Пітон 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

Пітон 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
Я можу підтвердити, що це рішення більше не функціонує. Ви можете виправити, змінити або прямо вилучити його.
Luís de Sousa

137

Щойно я дізнався (завдяки коментарю martineau ), що для того, щоб імпортувати класи з файлів у межах одного каталогу, ви зараз пишете на Python 3:

from .user import User
from .dir import Dir

8
якщо я спробую це ні, я отримую таку помилку, ValueError: Attempted relative import in non-packageале помилка зникає, коли я from user import User
переходжу

Я використовую з .fileloader імпорт Fileloader і отримую ImportError: не можу імпортувати ім’я "Fileloader"
Frikster

3
@Korpel: Після обговорення в stackoverflow.com/questions/11536764/… я розумію, що, якщо вищевказаний імпорт працює чи ні, залежить від: [1] того, як називається ваш скрипт (як пакет чи ні) [2] де фактичний робочий шлях - це коли ви виконуєте його [3], як заповнюється змінна шлях вашого середовища запуску
ecp

@Korpel: Я помітив, що. перед назвою модуля потрібно лише тоді, коли присутній файл init .py, якщо не файл. можна / треба пропустити
MUG4N

39

У вашому main.py:

from user import Class

де Classназва класу, який ви хочете імпортувати.

Якщо ви хочете викликати метод Class, ви можете зателефонувати за ним:

Class.method

Зверніть увагу, що __init__.pyв одному каталозі має бути порожній файл.


1
Що робити, якщо модуль, який ви намагаєтеся імпортувати, не має класів? Просто необроблені функції? У python 2 все, що мені потрібно було зробити, - це «модуль імпорту». Не працює в python 3, також не імпортує .module
Frikster,

2
Це працює в python3 після видалення __init__.py.
двигун сили

13

Ви можете імпортувати модуль і мати доступ через його ім'я, якщо ви не хочете змішувати функції та класи з вашими

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)

10

Чи не в Python3, __init__.pyце більше не потрібно . Якщо поточний каталог консолі - це каталог, де знаходиться скрипт python, все працює добре

import user

Однак це не буде працювати, якщо викликати з іншого каталогу, який не містить user.py.
У такому випадку використовуйте

from . import user

Це працює, навіть якщо ви хочете імпортувати звідти весь файл, а не лише клас.


2
Я використовував pylint в коді vs і мав проблеми з імпортом одного каталогу, який завжди позначався помилкою ( import userпідкреслено червоним кольором); змінено на відносний імпорт ( 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 з двох різних файлів

$ 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? ... що ми пропускаємо?
darkgaze

6

Пітон 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


-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

інший файл, ніж файли

з каталогу імпортуйте ваш файл


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

як так


3
Ця відповідь насправді не додає нічого більше, ніж інша відповідь, і вже не має пояснень. Чи є спосіб, яким ви могли б відредагувати свою відповідь, щоб додати або покращити її? Тому що в іншому випадку це означає, що ця відповідь була видалена або повністю видалена.
Das_Geek
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.