Bagaimana cara mengimpor kelas dalam direktori atau sub direktori yang sama?

676

Saya memiliki direktori yang menyimpan semua file .py .

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

Saya ingin menggunakan kelas dari user.py dan dir.py di main.py .
Bagaimana saya bisa mengimpor kelas-kelas Python ini ke main.py ?
Selanjutnya, bagaimana saya bisa mengimpor kelas Userjika user.py ada di dalam sub direktori?

bin/
    dir.py
    main.py
    usr/
        user.py
Bin Chen
sumber

Jawaban:

939

Python 2

Buat file kosong yang disebut __init__.pydi direktori yang sama dengan file. Itu akan menandakan ke Python bahwa "boleh mengimpor dari direktori ini".

Maka lakukan saja ...

from user import User
from dir import Dir

Hal yang sama berlaku jika file berada dalam subdirektori - beri tanda __init__.py dalam subdirektori, dan kemudian gunakan pernyataan impor reguler, dengan notasi titik. Untuk setiap level direktori, Anda perlu menambahkan jalur impor.

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

Jadi, jika direktori itu bernama "kelas", maka Anda akan melakukan ini:

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

Python 3

Sama seperti sebelumnya, tetapi awali nama modul dengan .jika tidak menggunakan subdirektori:

from .user import User
from .dir import Dir
Amber
sumber
14
Jika __init__.pyini tidak kosong, maka apa yang ada di __init__.pyadalah apa yang akan tersedia ketika Anda mengimpor paket (dan hal-hal tidak diimpor ke __init__.pytidak akan tersedia sama sekali).
Amber
23
Mengapa __init__.pyfile sama sekali dibutuhkan? Jika saya meletakkan ketiga file di direktori yang sama dan menjalankannya main.py, itu bisa importdari dua modul lainnya tanpa itu. Apa yang saya lewatkan?
martineau
30
Karena itulah cara Python mengidentifikasi direktori tempat Anda diizinkan mengimpor. Direktori skrip yang Anda jalankan adalah pengecualian - Anda selalu diizinkan untuk mengimpor darinya.
Amber
20
@nbro & Amber: FWIW, saya pikir sesuatu yang halus telah berubah sehubungan dengan __init__.pydan dapat mengimpor modul lain di direktori yang sama. Khususnya importmodul lain dalam direktori yang sama dengan __init__.pyfile itu sendiri yang bekerja di Python 2.7.8, gagal dalam Python 3.4.1. Untuk memperbaikinya saya harus mengawali masing-masing dengan nama subdirektori dan sebuah titik (yaitu import moduleharus diubah menjadi import subdirectory.module). Untungnya itu masih berfungsi di Python 2.7.8 setelah melakukan ini.
martineau
4
Saya dapat mengkonfirmasi bahwa solusi ini tidak lagi berfungsi. Anda mungkin ingin memperbaiki, mengubah atau menghapusnya.
Luís de Sousa
137

Saya baru tahu (terima kasih atas komentar martineau ) bahwa, untuk mengimpor kelas dari file dalam direktori yang sama, sekarang Anda akan menulis dengan Python 3:

from .user import User
from .dir import Dir
ecp
sumber
8
jika saya mencoba ini tidak saya mendapatkan kesalahan berikut ValueError: Attempted relative import in non-packagetetapi kesalahan hilang ketika saya mengubah kefrom user import User
Korpel
Saya menggunakan dari .fileloader mengimpor Fileloader dan mendapatkan ImportError: tidak dapat mengimpor nama 'Fileloader'
Frikster
3
@ Kalorpel: Mengikuti diskusi di stackoverflow.com/questions/11536764/... saya menyadari bahwa apakah impor yang diberikan di atas bekerja atau tidak tergantung pada: [1] bagaimana skrip Anda dipanggil (sebagai paket atau tidak) [2] di mana jalur kerja yang sebenarnya adalah ketika Anda menjalankannya [3] bagaimana variabel jalur dari lingkungan yang Anda jalankan terisi
ecp
@ Kalorp: Saya perhatikan itu. sebelum nama modul hanya diperlukan saat file .py init ada, jika bukan. dapat / harus dihilangkan.
MUG4N
40

Di Anda main.py:

from user import Class

dimana Class nama kelas yang ingin Anda impor.

Jika Anda ingin memanggil metode Class, Anda dapat memanggilnya menggunakan:

Class.method

Perhatikan bahwa harus ada yang kosong __init__.py file di direktori yang sama.

pengguna225312
sumber
1
Apa yang Anda lakukan jika modul yang Anda coba impor tidak memiliki kelas? Hanya fungsi mentah? Dalam python 2 yang harus saya lakukan adalah 'modul impor'. Tidak bekerja di python 3, juga tidak 'impor .module'
Frikster
2
Ini berfungsi di python3 setelah menghapus __init__.py.
engineforce
14

Anda dapat mengimpor modul dan memiliki akses melalui namanya jika Anda tidak ingin mencampur fungsi dan kelas dengan milik Anda

import util # imports util.py

util.clean()
util.setup(4)

atau Anda dapat mengimpor fungsi dan kelas ke kode Anda

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

Anda dapat menggunakan wildchar * untuk mengimpor semua yang ada di modul itu ke kode Anda

from util import *
clean()
setup(4)
A.Zaben
sumber
10

Dalam python3, __init__.pyadalah tidak lagi diperlukan . Jika direktori saat ini dari konsol adalah direktori di mana skrip python berada, semuanya berfungsi dengan baik

import user

Namun, ini tidak akan berfungsi jika dipanggil dari direktori lain, yang tidak mengandung user.py.
Dalam hal itu, gunakan

from . import user

Ini berfungsi bahkan jika Anda ingin mengimpor seluruh file, bukan hanya kelas dari sana.

lucidbrot
sumber
2
Saya menggunakan pylint dalam kode vs, dan mengalami masalah dengan impor direktori yang sama selalu ditandai sebagai kesalahan ( import userdigarisbawahi dalam warna merah); diubah ke impor relatif ( from . import user) dan linter tidak lagi menandai itu.
rbatt
9

Agar lebih mudah dipahami:

Langkah 1: mari kita pergi ke satu direktori, di mana semua akan dimasukkan

$ cd /var/tmp

Langkah 2: sekarang mari kita membuat file class1.py yang memiliki nama kelas Class1 dengan beberapa kode

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

Langkah 3: sekarang mari kita membuat file class2.py yang memiliki nama class Class2 dengan beberapa kode

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

Langkah 4: sekarang mari kita buat satu main.py yang akan dijalankan sekali untuk menggunakan Class1 dan Class2 dari 2 file yang berbeda

$ 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

Langkah 5: Jalankan program

$ python main.py

Outputnya adalah

[Class1 OK]: 
[Class2 OK]:
Hassan Nadeem
sumber
4
Dan apa yang terjadi jika ini tidak berhasil dan main.py tidak dapat membaca class1 atau class2? ... apa yang kita lewatkan?
darkgaze
6

Python 3


Sama directory.

mengimpor file:log.py

kelas impor: SampleApp().

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

atau

direktori adalah basic.

mengimpor dalam file: log.py.

kelas impor: SampleApp().

from basic import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()
Yasith Praharshana
sumber
5
from user import User 
from dir import Dir 
demo
sumber
Ini bekerja untuk saya tanpa memiliki file init .py untuk Python 2.7 dan Python 3.6.
imsrgadich
1
@imsrgadich berfungsi selama Anda menjalankan python di direktori yang berisi file. Ini merupakan pengecualian. Lihat komentar ini
Ciprian Tomoiagă
5

Jika user.py dan dir.py tidak termasuk kelas, maka

from .user import User
from .dir import Dir

tidak bekerja. Anda kemudian harus mengimpor sebagai

from . import user
from . import dir
Andreas Foteas
sumber
0

Saya tidak yakin mengapa ini bekerja tetapi menggunakan Pycharm build from file_in_same_dir import class_name

IDE mengeluhkannya tetapi tampaknya masih berfungsi. Saya menggunakan Python 3.7

stingMantis
sumber
-2

Terlalu singkat, Buat file __init__.pyadalah direktori kelas dan kemudian impor ke skrip Anda seperti berikut (Impor semua huruf besar)

from classes.myscript import *

Hanya mengimpor kelas yang dipilih

from classes.myscript import User
from classes.myscript import Dir
Syafiq
sumber
4
Impor wildcard seperti yang terlihat dalam jawaban ini umumnya dianggap gaya buruk seperti dijelaskan dalam PEP 8 .
V02460
-3

untuk mengimpor dari direktori yang sama

from . import the_file_you_want_to_import 

untuk mengimpor dari sub direktori, direktori harus berisi

init .py

file selain file Anda kemudian

dari direktori import your_file

rojo_hlerr
sumber
3
Saya tidak berpikir jawaban ini menambahkan apa pun yang tidak dijawab oleh jawaban lain, dan juga bukan ringkasan komprehensif dari jawaban lainnya. Jadi saya ingin tahu mengapa Anda menulisnya
lucidbrot
-3

Python3

menggunakan

from .user import User inside dir.py file

dan

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

seperti itu

icharis
sumber
3
Jawaban ini tidak benar-benar menambahkan apa pun lebih dari jawaban yang sudah dilakukan, dan tidak memiliki penjelasan. Apakah ada cara yang bisa Anda lakukan mengedit jawaban Anda untuk ditambahkan atau ditingkatkan? Karena kalau tidak, itu akan diturunkan seperti jawaban ini atau dihapus seluruhnya.
Das_Geek