Nhập Script từ Thư mục gốc


81

Làm cách nào để nhập một mô-đun (tệp python) nằm trong thư mục mẹ?

Cả hai thư mục đều có __init__.pytệp trong đó nhưng tôi vẫn không thể nhập tệp từ thư mục mẹ?

Trong bố cục thư mục này, Tập lệnh B đang cố gắng nhập Tập lệnh A:

Folder A:
   __init__.py
   Script A:
   Folder B:
     __init__.py
     Script B(attempting to import Script A)

Đoạn mã sau trong Tập lệnh B không hoạt động:

import ../scriptA.py # I get a compile error saying the "." is invalid

Không chính xác trả lời câu hỏi của bạn, nhưng nếu bạn chạy init py bên trong thư mục A và cố gắng và nhập khẩu thư mục B hoặc Script B, Script A sẽ được nhập thành công bên trong Script B.
Michael0x2a

Có thể có bản sao của Nhập mô-đun từ thư mục mẹ
Kaibo

Câu trả lời:


78

Bạn không nhập các tập lệnh bằng Python mà bạn nhập các mô-đun. Một số mô-đun python cũng là tập lệnh mà bạn có thể chạy trực tiếp (chúng thực hiện một số công việc hữu ích ở cấp mô-đun).

Nói chung, nên sử dụng nhập khẩu tuyệt đối hơn là nhập khẩu tương đối.

toplevel_package/
├── __init__.py
├── moduleA.py
└── subpackage
    ├── __init__.py
    └── moduleB.py

Trong moduleB:

from toplevel_package import moduleA

Nếu bạn muốn chạy moduleB.pydưới dạng tập lệnh thì hãy đảm bảo rằng thư mục mẹ cho toplevel_packagenằm trong của bạn sys.path.


8
Và tại sao không nên sử dụng "hacks" đường dẫn sys trong trường hợp này? Python khiến bạn khó thực hiện những gì bạn muốn ở đây mà không có chúng. Chính xác thì nhược điểm ở đây là gì?
BT

4
@BT « sys.path.append(path_to_parent)» không phải là câu trả lời cho cách sửa «" import ../scriptA.py # Tôi gặp lỗi biên dịch cho biết câu hỏi "." Không hợp lệ "» . Có những trường hợp mà việc thay đổi sys.pathcó thể hữu ích, ví dụ: nếu bản thân python đã thực hiện nó hoặc mô-đun 3 bên xử lý tất cả các trường hợp góc đã thực hiện nó một cách chính xác, ví dụ: import autopath; autopath.add_toplevel_to_syspath()tự động thêm thư mục mẹ của toplevel_package sys.pathđể cho phép thực thi mô-đun nội bộ trực tiếp dưới dạng script (hoặc trong REPL) từ bất kỳ thư mục nào mà không cần cài đặt PYTHONPATH hoặc (virtualenv) thích hợp.
jfs 16/10/12

3
@JFSebastian Có một số loại đề xuất cho một tính năng cho phép chúng tôi nói rõ ràng đâu là thư mục chính hoặc gói của toàn bộ dự án để chúng tôi không phải quan tâm đến việc thêm thư mục mẹ để sys.pathchúng tôi có thể chạy các mô-đun con. tập tin chính hoặc tập lệnh? Tôi có một dự án mà tôi thực sự cần chạy các tập lệnh cả dưới dạng chính hoặc dưới dạng mô-đun, được nhập vào, nhưng tôi cần thực hiện hàng tấn hack thêm đường dẫn để sys.pathchúng hoạt động trong cả hai trường hợp. Làm việc trong virtualenv hoặc sử dụng công cụ cài đặt có hoạt động bằng cách nào đó không? Tôi thực sự đang đấu tranh với điều này ...
nbro

2
@nbro tính năng được gọi pip install main-package. Bạn có thể chạy "submodules" rồi (chỉ cần sử dụng tên tuyệt đối của chúng, ví dụ, python -ma.b.c). Nếu nó không rõ ràng; hỏi
jfs

11
Giải pháp này không hiệu quả với tôi. Nó phát sinh: "ImportError: Không có mô-đun nào có tên là toplevel_package"
thông minh

35

Từ các tài liệu :

from .. import scriptA

Bạn có thể thực hiện việc này trong các gói, nhưng không phải trong các tập lệnh mà bạn chạy trực tiếp. Từ liên kết trên:

Lưu ý rằng cả nhập khẩu tương đối rõ ràng và ngầm định đều dựa trên tên của mô-đun hiện tại. Vì tên của mô-đun chính luôn là "__main__", các mô-đun được thiết kế để sử dụng làm mô-đun chính của ứng dụng Python phải luôn sử dụng nhập tuyệt đối.

Nếu bạn tạo một tập lệnh nhập ABB, bạn sẽ không nhận được ValueError.


29
ValueError: Đã cố gắng nhập khẩu tương đối trong không gói
jgritty

3
@jgritty, đó là bởi vì bạn đang thực hiện nó trong một tập lệnh mà bạn đang chạy trực tiếp.
Rob Wouters

2
Vâng bạn đã đúng. Nó sẽ có tác dụng nếu bạn gọi một kịch bản rằng hàng nhập khẩu sau đó Script B.
jgritty

6
@jgritty sys.path.append("..")là những gì bạn đang tìm kiếm

5
Cuối cùng, 6 năm sau, đoạn mã mà tôi đang tìm kiếm!
jgritty

5

Nếu bạn muốn chạy tập lệnh trực tiếp, bạn có thể:

  1. Thêm đường dẫn của FolderA vào biến môi trường (PYTHONPATH ).
  2. Thêm đường dẫn đến sys.pathtrong tập lệnh của bạn.

Sau đó:

import module_you_wanted
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.