Nhập gói python từ thư mục cục bộ vào trình thông dịch


86

Tôi đang phát triển / thử nghiệm một gói trong thư mục cục bộ của mình. Tôi muốn nhập nó trong trình thông dịch (v2.5), nhưng sys.path không bao gồm thư mục hiện tại. Ngay bây giờ tôi gõ vào sys.path.insert(0,'.'). Có cách nào tốt hơn?

Cũng thế,

from . import mypackage

không thành công với lỗi này:

ValueError: Attempted relative import in non-package

Bạn đọc những thứ đó ở đâu "." là một mô-đun Python?
S.Lott

16
@Lott: Đó là một con đường nhập khẩu tương đối mô tả ở đây: docs.python.org/reference/...
projectshave

1
Bạn có thể muốn xem hướng dẫn dứt khoát này chrisyeh96.github.io/2017/08/08/…
Kevin Zhu

Câu trả lời:


44

Bạn chỉ có thể sử dụng tính năng nhập tương đối từ trong một mô-đun đã được nhập lần lượt như một phần của gói - tập lệnh hoặc trình thông dịch tương tác của bạn không phải vậy, tất nhiên from . import(có nghĩa là "nhập từ cùng một gói mà tôi đã nhập từ đó") không không hoạt động. import mypackagesẽ ổn thôi khi bạn đảm bảo các thư mục cha của mypackagelà ở sys.path(cách bạn quản lý để có được thư mục hiện tại của bạn đi từ sys.pathtôi không biết - làm bạn có một cái gì đó kỳ lạ trong site.py, hoặc ...)

Để có được thư mục trở lại hiện tại của bạn vào sys.pathđó là trong thực tế cách nào tốt hơn so với đặt nó ở đó.


Python 2.5 dành cho Ubuntu 8.10 không có thư mục hiện tại (chuỗi trống) trong sys.path cho trình thông dịch. Tôi đã không thay đổi bất cứ điều gì, vì vậy bằng cách nào đó nó đã được vận chuyển theo cách đó. Tôi vừa cài đặt 3.0 và sys.path KHÔNG có '' trong sys.path.
projectshave

@projectshave, OK, Ubuntu chắc chắn có lý do của họ! Tôi đã không nhận thấy điều đó trong 8.04 (những gì chúng tôi hiện đang sử dụng tại nơi làm việc) nhưng có lẽ tôi đã không chú ý đủ.
Alex Martelli,

1
Tôi sai một phần. Python được gọi từ một trình bao có thư mục hiện tại trong sys.path. Python được gọi từ Emacs không có thư mục hiện tại. Thật kỳ lạ.
projectshave

1
À tốt, sau đó là Emacs có lý do của họ trái ngược với Ubuntu (với tư cách là một người dùng vim, tôi không thực sự biết ;-). Bạn có thể chèn '.' trong sys.path của bạn, tất nhiên không có.
Alex Martelli,

@Alex Martelli: Cảm ơn bạn rất nhiều! Tôi đã tìm kiếm và tìm kiếm giải pháp cho lý do tại sao tiện ích bổ sung của tôi (cho Anki) cần một câu lệnh nhập khác khi được chạy 'cục bộ' dưới dạng tập lệnh. Thay vào đó, khi tôi thêm một phương thức local_launch () và nhập / khởi chạy toàn bộ từ một tập lệnh bên ngoài thư mục gói, nó hoạt động như một sự quyến rũ!
Jon Coombs

17

Xem tài liệu cho sys.path:

http://docs.python.org/library/sys.html#sys.path

Để trích:

Nếu thư mục tập lệnh không có sẵn (ví dụ: nếu trình thông dịch được gọi tương tác hoặc nếu tập lệnh được đọc từ đầu vào chuẩn), đường dẫn [0] là chuỗi trống, hướng Python đến tìm kiếm mô-đun trong thư mục hiện tại trước tiên.

Vì vậy, không cần sử dụng sys.path nếu bạn đang khởi động trình thông dịch python từ thư mục chứa mô-đun của mình.

Ngoài ra, để nhập gói của bạn, chỉ cần làm:

import mypackage

Vì thư mục chứa gói đã có trong sys.path, nó sẽ hoạt động tốt.


1
Nó sẽ không thành công nếu một tên tệp tương tự tồn tại ở một nơi khác trong env đang hoạt động.
JAR.JAR.beans

@ JAR.JAR.beans thư mục làm việc hiện tại phải là thư mục đầu tiên trong sys.pathđó các tệp sẽ được tìm thấy trước các tệp ở bất kỳ nơi nào khác trong môi trường làm việc.
SpoonMeiser

3
Điểm tốt. Đó là, nếu chúng tôi chạy tệp từ thư mục cục bộ. Trong trường hợp đó là một số thư mục khác và trong trường hợp cần thay đổi đường dẫn sys.path - điều đó có nghĩa sys.path.insert(0, new_path)là hơn sys.path.append(new_path).
JAR.JAR.beans

14

Nếu bạn muốn chạy một tập lệnh python chưa sửa đổi để nó nhập các thư viện từ một thư mục cục bộ cụ thể, bạn có thể đặt PYTHONPATHbiến môi trường - ví dụ: trong bash:

export PYTHONPATH=/home/user/my_libs
python myscript.py

Nếu bạn chỉ muốn nó nhập từ thư mục làm việc hiện tại, hãy sử dụng .ký hiệu:

export PYTHONPATH=.
python myscript.py

Xuất PYTHONPATH bao gồm lập trình bên ngoài python (ví dụ: trong bash). Ngoài ra, trong docs.python.org/3/using/cmdline.html đã nêu rõ rằng " đường dẫn tìm kiếm mặc định phụ thuộc vào cài đặt ".
ilias iliadis 23/03/18

13

Giữ nó đơn giản:

 try:
     from . import mymodule     # "myapp" case
 except:
     import mymodule            # "__main__" case

7
Tôi thích giải pháp này, nó là đơn giản nhất. Câu hỏi còn lại duy nhất là tại sao quy tắc "duy nhất một cách để thực hiện" được coi là tùy chọn khi thực hiện nhập khẩu ... Nghiêm túc mà nói, có khoảng 15 cách để khai báo và tổ chức các gói hàng, tất cả đều có nhược điểm
Léo Germond

5

Một cách đơn giản để làm cho nó làm việc là để chạy kịch bản của bạn từ thư mục cha sử dụng python của -mlá cờ, ví dụ python -m packagename.scriptname. Rõ ràng trong tình huống này, bạn cần một __init__.pytệp để biến thư mục của mình thành một gói.


5

Bên trong một gói nếu có setup.py , thì tốt hơn nên cài đặt nó

pip install -e .

3

Sử dụng sys.pathnên bao gồm thư mục hiện tại đã.

Thử:

import .

hoặc là:

from . import sth

tuy nhiên nó có thể không phải là một thực tiễn tốt, vì vậy tại sao không chỉ sử dụng:

import mypackage

5
Vấn đề với <import mypackage> là nó sẽ tải gói từ env python toàn cục, nó có thể tải gói / tệp từ thư mục cục bộ, nhưng nó cũng có thể tải một số mypackge ngẫu nhiên khác có trong env đang hoạt động.
JAR.JAR.beans

2

Đến bữa tiệc hơi muộn, nhưng đây là điều làm việc cho tôi:

>>> import sys
>>> sys.path.insert(0, '')

Rõ ràng, nếu có một chuỗi trống, Python biết rằng nó sẽ tìm trong thư mục hiện tại. Tôi không có chuỗi trống sys.path, điều này gây ra lỗi này.


0

Tôi đã từng pathlibthêm thư mục mô-đun của mình vào đường dẫn hệ thống của mình vì tôi muốn tránh cài đặt mô-đun dưới dạng gói và phản hồi @maninthecomputer không hoạt động đối với tôi

import sys
from pathlib import Path

cwd = str(Path(__file__).parent)
sys.path.insert(0, cwd)
from my_module import my_function
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.