Nhập mô-đun từ thư mục con


104

Tôi muốn nhập các thư mục con dưới dạng mô-đun. Do đó mọi thư mục con đều chứa a __init__.py. Cấu trúc thư mục của tôi như thế này:

src\
  main.py
  dirFoo\
    __init__.py
    foofactory.py
    dirFoo1\
      __init__.py
      foo1.py
    dirFoo2\
      __init__.py
      foo2.py

Trong tập lệnh chính của tôi, tôi nhập

from dirFoo.foofactory import FooFactory

Trong tệp gốc này, tôi bao gồm các mô-đun phụ:

from dirFoo1.foo1 import Foo1
from dirFoo2.foo2 import Foo2

Nếu tôi gọi foofactory của mình, tôi gặp lỗi, python đó không thể nhập các mô-đun con foo1 và foo2:

Traceback (most recent call last):
  File "/Users/tmp/src/main.py", line 1, in <module>
from dirFoo.foofactory import FooFactory
  File "/Users/tmp/src/dirFoo/foofactory.py", line 1, in    <module>
from dirFoo1.foo1 import Foo1
    ImportError: No module named dirFoo1.foo1

Câu trả lời:


136

Không cần phải gây rối với của bạn PYTHONPATHhoặc sys.pathở đây.

Để sử dụng đúng cách nhập tuyệt đối trong một gói, bạn cũng nên bao gồm cả tên gói "gốc", ví dụ:

from dirFoo.dirFoo1.foo1 import Foo1
from dirFoo.dirFoo2.foo2 import Foo2

Hoặc bạn có thể sử dụng nhập khẩu tương đối :

from .dirfoo1.foo1 import Foo1
from .dirfoo2.foo2 import Foo2

47
Một điều cần nhớ! thêm __init__.pyvào mọi thư mục con mà bạn đang nhập.
Aziz Alto

6
Trống __init__.pycó thể thực hiện công việc.
cerebrou

1
Cú pháp sẽ như thế nào nếu trước đó Foo1nằm trong thư mục mẹ và một mã được mã hóa như thế nào from Foo1 import *. Có cách nào để đạt được hiệu quả tương tự để bạn không phải thêm tiền tố vào mọi thứ Foo1không?
jxramos

1
@AzizAlto: nếu không có nhận xét của bạn thì giải pháp này không hữu ích lắm
Alex

21

Chỉ cần thông báo ở đây. (từ một newbee, keviv22)

Đừng bao giờ và không bao giờ vì lợi ích của riêng bạn, hãy đặt tên cho các thư mục hoặc tệp bằng các ký hiệu như "-" hoặc "_". Nếu bạn làm như vậy, bạn có thể gặp phải một số vấn đề. như của tôi, chẳng hạn, mặc dù lệnh nhập của bạn là chính xác, bạn sẽ không thể nhập thành công các tệp mong muốn có sẵn bên trong các thư mục được đặt tên như vậy.

Tên thư mục không hợp lệ như sau:

  • Chung-Lớp-Thư mục
  • Generic_Classes_Folder

tên Thư mục hợp lệ cho ở trên:

  • GenericClassesFolder hoặc Genericclassesfolder hoặc genericClassesFolder (hoặc tương tự như thế này mà không có bất kỳ dấu cách hoặc ký hiệu đặc biệt nào giữa các từ)

Tôi đã làm gì sai:

xem xét cấu trúc tệp.

Parent
   . __init__.py
   . Setup
     .. __init__.py
     .. Generic-Class-Folder
        ... __init__.py
        ... targetClass.py
   . Check
     .. __init__.py
     .. testFile.py

Tôi muốn làm gì?

  • từ testFile.py, tôi muốn nhập tệp 'targetClass.py' bên trong tệp Chung-Lớp-Thư mục để sử dụng hàm có tên "functionExecute" trong tệp 'targetClass.py'

Tôi đã làm lệnh gì?

  • từ 'testFile.py', đã viết lệnh, from Core.Generic-Class-Folder.targetClass import functionExecute
  • Có lỗi như SyntaxError: invalid syntax

Đã thử nhiều tìm kiếm và xem nhiều câu hỏi về dòng chảy chồng lên nhau và không thể quyết định điều gì đã xảy ra. Tôi đã kiểm tra chéo các tệp của mình nhiều lần, tôi đã sử dụng__init__.py tệp, đường dẫn môi trường được chèn và vô cùng lo lắng rằng đã xảy ra lỗi ......

Và sau một thời gian dài, tôi đã tìm ra điều này khi nói chuyện với một người bạn của mình. Tôi hơi ngu ngốc khi sử dụng các quy ước đặt tên như vậy. Tôi không bao giờ nên sử dụng khoảng trắng hoặc các ký hiệu đặc biệt để xác định tên cho bất kỳ thư mục hoặc tệp nào. Vì vậy, đây là những gì tôi muốn truyền đạt. Chúc bạn ngày mới tốt lành!

(xin lỗi vì bài đăng quá lớn về điều này ... chỉ để cho sự thất vọng của tôi qua đi .... :) Cảm ơn!)


22
Dấu cách và dấu gạch ngang ("-") sẽ gây ra điều này, nhưng dấu gạch dưới ("_") vẫn hoạt động tốt.
cowlinator

6

Đặt biến môi trường PYTHONPATH của bạn. Ví dụ như thế này PYTHONPATH =.: .. (cho họ * nix).

Ngoài ra, bạn có thể thêm thủ công thư mục hiện tại của mình (src trong trường hợp của bạn) vào pythonpath:

import os
import sys
sys.path.insert(0, os.getcwd())

2

Giả sử dự án của bạn được cấu trúc theo cách này:

+---MyPythonProject
|   +---.gitignore
|   +---run.py
|   |   +---subscripts
|   |   |   +---script_one.py
|   |   |   +---script_two.py

Bên trong run.py, bạn có thể nhập các tập lệnh một và hai bằng cách:

from subscripts import script_one as One
from subscripts import script_two as Two

Bây giờ, vẫn bên trong run.py, bạn sẽ có thể gọi các phương thức của chúng bằng:

One.method_from_one(param)
Two.method_from_two(other_param)

1

Chỉ cần tạo một tệp ___init____.py trống và thêm nó vào thư mục gốc cũng như tất cả thư mục con / thư mục của ứng dụng python của bạn nơi bạn có các mô-đun python khác.


-2

Gặp sự cố ngay cả khi init .py tồn tại trong thư mục con và tất cả những gì bị thiếu là thêm 'as' sau khi nhập

from folder.file import Class as Class
import folder.file as functions
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.