Làm thế nào để nhập lớp trong cùng thư mục hoặc thư mục con?


675

Tôi có một thư mục lưu trữ tất cả các tập tin .py .

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

Tôi muốn sử dụng lớp từ user.pydir.py trong main.py .
Làm cách nào tôi có thể nhập các lớp Python này vào main.py ?
Hơn nữa, làm cách nào tôi có thể nhập lớp Usernếu user.txt nằm trong thư mục con?

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

Xem thêm câu trả lời trong Python: nhập tệp từ thư mục con .
Trilarion

Câu trả lời:


934

Con trăn 2

Tạo một tệp trống được gọi __init__.pytrong cùng thư mục với các tệp. Điều đó sẽ biểu thị cho Python rằng "bạn có thể nhập từ thư mục này".

Sau đó, chỉ cần làm ...

from user import User
from dir import Dir

Điều tương tự cũng đúng nếu các tệp nằm trong thư mục con - cũng đặt một __init__.pythư mục con vào thư mục con, sau đó sử dụng các câu lệnh nhập thông thường, với ký hiệu dấu chấm. Đối với mỗi cấp độ của thư mục, bạn cần thêm vào đường dẫn nhập.

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

Vì vậy, nếu thư mục được đặt tên là "lớp", thì bạn sẽ làm điều này:

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

Con trăn 3

Tương tự như trước, nhưng tiền tố tên mô-đun với .nếu không sử dụng thư mục con:

from .user import User
from .dir import Dir

14
Nếu __init__.pykhông có sản phẩm nào, sau đó bất cứ điều gì là trong __init__.pylà những gì sẽ có sẵn khi bạn nhập gói (và những thứ không được nhập vào __init__.pysẽ không có sẵn ở tất cả).
Amber

23
Tại sao một __init__.pytập tin cần thiết ở tất cả? Nếu tôi đặt cả ba tệp trong cùng một thư mục và chạy main.py, nó có thể importtừ hai mô-đun còn lại tốt mà không có nó. Tôi đang thiếu gì?
martineau

30
Bởi vì đó là cách Python xác định các thư mục mà bạn được phép nhập. Thư mục của tập lệnh bạn đang chạy là một ngoại lệ - bạn luôn được phép nhập từ tập lệnh.
Amber

20
@nbro & Amber: FWIW, tôi nghĩ rằng một cái gì đó tinh tế đã thay đổi liên quan đến __init__.pyvà có thể nhập các mô-đun khác trong cùng thư mục. Cụ thể importlà các mô-đun khác trong cùng thư mục với __init__.pychính tệp đã hoạt động trong Python 2.7.8, đã thất bại trong Python 3.4.1. Để sửa lỗi, tôi phải đặt tiền tố cho mỗi tên trong số chúng bằng tên của thư mục con và dấu chấm (nghĩa là import modulephải đổi thành import subdirectory.module). May mắn là nó vẫn hoạt động trong Python 2.7.8 sau khi làm điều này.
martineau

4
Tôi có thể xác nhận giải pháp này không còn hoạt động. Bạn có thể muốn sửa, sửa đổi hoặc hoàn toàn xóa nó.
Luís de Sousa

137

Tôi mới biết (nhờ nhận xét của martineau ) rằng, để nhập các lớp từ các tệp trong cùng thư mục, bây giờ bạn sẽ viết bằng Python 3:

from .user import User
from .dir import Dir

7
Nếu tôi thử điều này, tôi sẽ không gặp lỗi sau ValueError: Attempted relative import in non-packagenhưng lỗi sẽ biến mất khi tôi đổi thànhfrom user import User
Korpel

Tôi sử dụng từ .fileloader nhập Fileloader và nhận ImportError: không thể nhập tên 'Fileloader'
Frikster

3
@Korpel: Theo dõi các cuộc thảo luận trong stackoverflow.com/questions/11536764/ nam tôi nhận ra rằng việc nhập khẩu đã cho ở trên có hoạt động hay không phụ thuộc vào: [1] cách tập lệnh của bạn được gọi (như gói hay không) [2] đường dẫn công việc thực tế là khi bạn thực thi nó [3] cách biến đường dẫn của môi trường chạy của bạn được tạo ra
ecp

@Korpel: Tôi nhận thấy rằng. trước tên mô-đun chỉ được yêu cầu khi có tệp init .py, nếu không phải là. có thể / phải được bỏ qua.
MUG4N

39

Trong của bạn main.py:

from user import Class

nơi Classlà tên của lớp bạn muốn nhập.

Nếu bạn muốn gọi một phương thức Class, bạn có thể gọi nó bằng cách sử dụng:

Class.method

Lưu ý rằng nên có một __init__.pytệp trống trong cùng thư mục.


1
Bạn làm gì nếu mô-đun bạn đang cố gắng nhập không có lớp? Chỉ là hàm thô? Trong python 2, tất cả những gì tôi phải làm là 'nhập mô-đun'. Không hoạt động trong python 3, cũng không 'nhập .module'
Frikster

2
Điều này hoạt động trong python3 sau khi xóa __init__.py.
lực lượng động cơ

13

Bạn có thể nhập mô-đun và có quyền truy cập thông qua tên của nó nếu bạn không muốn trộn các hàm và lớp với của bạn

import util # imports util.py

util.clean()
util.setup(4)

hoặc bạn có thể nhập các hàm và các lớp vào mã của bạn

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

bạn có thể sử dụng ký tự đại diện * để nhập mọi thứ trong mô-đun đó vào mã của mình

from util import *
clean()
setup(4)

10

Trong python3, __init__.pykhông còn cần thiết . Nếu thư mục hiện tại của bàn điều khiển là thư mục chứa tập lệnh python, mọi thứ đều hoạt động tốt với

import user

Tuy nhiên, điều này sẽ không hoạt động nếu được gọi từ một thư mục khác, không chứa user.py.
Trong trường hợp đó, sử dụng

from . import user

Điều này hoạt động ngay cả khi bạn muốn nhập toàn bộ tệp thay vì chỉ một lớp từ đó.


2
Tôi đang sử dụng pylint trong mã vs và gặp sự cố với nhập cùng thư mục luôn bị gắn cờ là lỗi ( import userđược gạch chân màu đỏ); đã thay đổi thành nhập tương đối ( from . import user) và kẻ nói dối không còn gắn cờ nó.
rbatt

9

Để làm cho nó đơn giản hơn để hiểu:

Bước 1: cho phép đi đến một thư mục, nơi tất cả sẽ được bao gồm

$ cd /var/tmp

Bước 2: bây giờ, hãy tạo một tệp class1.py có tên lớp Class1 với một số mã

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

Bước 3: bây giờ hãy tạo một tệp class2.py có tên lớp Class2 với một số mã

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

Bước 4: bây giờ, hãy tạo một main.txt sẽ được thực thi một lần để sử dụng Class1 và Class2 từ 2 tệp khác nhau

$ 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

Bước 5: Chạy chương trình

$ python main.py

Đầu ra sẽ là

[Class1 OK]: 
[Class2 OK]:

4
Và điều gì xảy ra nếu điều này không hoạt động và main.txt không thể đọc class1 hoặc class2? ... chúng ta còn thiếu gì?
bóng tối

6

Con trăn 3


Giống nhau directory.

nhập tệp:log.py

lớp nhập khẩu : SampleApp().

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

hoặc là

thư mục là basic.

nhập trong tệp : log.py.

lớp nhập khẩu : SampleApp().

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

5
from user import User 
from dir import Dir 

Điều này làm việc cho tôi mà không cần có tệp init .py cho cả Python 2.7 và Python 3.6.
imsrgadich

1
@imsrgadich nó hoạt động miễn là bạn đang chạy python trong thư mục chứa các tệp. Đây là một ngoại lệ. Xem bình luận này
Ciprian Tomoiagă

5

Nếu user.py và dir.py không bao gồm các lớp thì

from .user import User
from .dir import Dir

không hoạt động. Sau đó bạn nên nhập dưới dạng

from . import user
from . import dir

0

Tôi không chắc tại sao điều này hoạt động nhưng sử dụng Pycharm build from file_in_same_dir import class_name

IDE phàn nàn về nó nhưng có vẻ như nó vẫn hoạt động. Tôi đang sử dụng Python 3.7


-2

Chỉ quá ngắn gọn, Tạo một tệp __init__.pylà thư mục lớp và sau đó nhập nó vào tập lệnh của bạn như sau (Nhập tất cả trường hợp)

from classes.myscript import *

Chỉ nhập các lớp đã chọn

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

4
Nhập khẩu ký tự đại diện như đã thấy trong câu trả lời này thường được coi là kiểu xấu như được mô tả trong PEP 8 .
V02460

-3

để nhập từ cùng một thư mục

from . import the_file_you_want_to_import 

để nhập từ thư mục con thư mục nên chứa

init .py

tập tin khác với tập tin của bạn sau đó

từ thư mục nhập your_file


3
Tôi không nghĩ câu trả lời này thêm bất cứ điều gì mà các câu trả lời khác không có, và cũng không phải là một bản tóm tắt toàn diện về các câu trả lời khác. Vì vậy, tôi tự hỏi tại sao bạn viết nó
lucidbrot

-3

Python3

sử dụng

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

như vậy


3
Câu trả lời này không thực sự thêm bất cứ điều gì nhiều hơn câu trả lời khác đã làm và không có lời giải thích. Có một số cách bạn có thể chỉnh sửa câu trả lời của bạn để thêm hoặc cải thiện nó? Bởi vì nếu không, nó sẽ bị đánh giá thấp như câu trả lời này đã bị xóa hoặc xóa hoàn toàn.
Das_Geek
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.