Làm cách nào để thêm mô-đun Python vào syspath?


69

Tôi có một cấu trúc tập tin như thế này:

Folder
   Common
      foo1.py
   TestFolder
      foo2.py

Tôi muốn nhập khẩu foo2.pyfoo1.py. Tôi đã thử nhưng nó không hoạt động trên Ubuntu:

sys.path.append(os.path.abspath('../../'))
from Common import foo1.py

Bạn có một __init__.pytập tin trong thư mục của bạn? đây là cách python tạo ra các gói và cho phép bạn nhập các mô-đun từ gói đó. guide.python-distribution.org/creation.html
Bryan

Tôi có tệp init.py trong Common và trong TestFolder
user284474

bạn cần nó trong thư mục Thư mục cũng như trong các thư mục phụ nếu bạn muốn nhập
Bryan

Init này .py là trống rỗng?
dùng284474

1
Vâng, nó có thể trống rỗng. Trừ khi bạn cần một cấu hình nhất định cho gói của mình nhưng bạn sẽ ổn với nó trống
Bryan

Câu trả lời:


115

Làm thế nào python tìm thấy các mô-đun của nó

Được thực hiện nghiêm ngặt, một mô-đun là một tệp python, trong khi gói là một thư mục chứa các tệp python, kèm theo một tệp (có thể để trống) có tên __init__.py, để nói với python đó là một gói để nhập mô-đun từ đó. Trong cả hai trường hợp, các mô-đun cần .pyphần mở rộng của chúng , nhưng việc nhập chúng được thực hiện mà không cần (xem thêm bên dưới).

Theo mặc định, Python tìm các mô-đun và gói của nó trong $PYTHONPATH.

Để tìm hiểu những gì được bao gồm trong $ PYTHONPATH, hãy chạy đoạn mã sau trong python (3):

import sys
print(sys.path)

Cách thêm thư mục

Thỉnh thoảng

Từ trong tệp python, thỉnh thoảng bạn có thể thêm (các) đường dẫn vào đường dẫn mặc định bằng cách thêm các dòng sau vào phần đầu của ứng dụng hoặc tập lệnh python của bạn:

import sys
sys.path.insert(0, "/path/to/your/package_or_module")

Ví dụ:

nếu tôi có một thư mục: /home/myname/pythonfilesvà tôi muốn nhập tệp module_1.py, nằm trong thư mục đó, tôi thêm phần này vào phần đầu của mã:

import sys
sys.path.insert(0, "/home/myname/pythonfiles")

Và tôi chỉ có thể nhập tệp module_1.pybằng cách:

import module_1

Khi tôi tạo một gói và muốn nhập (các) mô-đun từ gói, tôi cần tạo một thư mục $PYTHONPATHchứa, chứa các mô-đun, kèm theo một tệp (có thể để trống) được gọi là__init__.py

Ví dụ:

Để nhập từ gói (thư mục) được gọi my_packagetrong /home/myname/pythonfiles, hãy thêm /home/myname/pythonfilesđường dẫn vào $PYTHONPATH, như trong ví dụ 1 và nhập mô-đun được gọi module_2.py(bên trong thư mục gói) chỉ bằng: `

from <packagename> import module_2

Thêm thư mục vào $PYTHONPATHvĩnh viễn:

Thêm dòng sau vào ~/.profiletập tin của bạn .

export PYTHONPATH=$PYTHONPATH:/path/you/want/to/add

Thư mục con

Từ trong một gói, các thư mục con không được bao gồm như thế; bạn cần "xâu chuỗi" các thư mục. Để nhập một mô-đun module_3.py, bên trong thư mục subfolderbên trong thư mục packagename:

import packagename.subfolder.module_3

Với thực tế là tất cả các thư mục con trong gói bao gồm __init__.pytệp riêng của họ .

Khi một mô-đun nằm trong cùng thư mục với tập lệnh hoặc ứng dụng

Không cần phải chèn đường dẫn đến một mô-đun khi nó nằm trong cùng thư mục với tập lệnh hoặc ứng dụng, nó sẽ tự động được thêm vào.

Thí dụ:

Nếu tôi có một thư mục, chứa script.pymodule.py, tôi chỉ có thể nhập mô-đun bằng cách:

import module

Tôi cũng muốn đề xuất đọc python.org/dev/peps/pep-0328 , đặc biệt nếu bạn đang nhắm mục tiêu Python 3 (hoặc dự định nhắm mục tiêu trong tương lai)
zaadeh

Tại sao printenv PYTHONPATHkhông có gì?
Stevie G

1
sys.path.append("/path/to/your/package_or_module")cũng thêm một đường dẫn đến mặc định và nó ít gây nhầm lẫn hơn. So với sys.path.insert(0,...)đó 0là một đối số đầu tiên.
Paul Rougieux

1
@PaulRougieux: Vấn đề với phụ thêm vào con đường là mô-đun của bạn có thể đã tồn tại ở đâu đó trong đường dẫn (trong một tập tin .egg ví dụ) và bạn sẽ nhận rằng phiên bản của mô-đun của bạn thay vì một trong tập tin của bạn.
sủa

6

Cách chính xác để sử dụng nhập tương đối là:

from ..Common import foo1

Và bạn cũng cần một __init__.pytrong tất cả các thư mục của bạn.


1
Cám ơn. Nhưng nếu tôi có một mô-đun là hai thư mục. Làm thế nào để tôi nhập nó? từ .... Thư mục không hoạt động
user284474

Nó hoạt động với một cấp độ duy nhất?
Sylvain Pineau

Với một cấp độ duy nhất nó hoạt động.
dùng284474

ok, bạn có thể vui lòng chấp nhận câu trả lời này? đối với đa cấp mặc dù bạn có thể hỏi một câu hỏi khác nhưng trước tiên hãy xem câu hỏi này và câu trả lời này để biết cách tốt nhất để gọi các mô-đun của bạn trong một gói
Sylvain Pineau

Điều này đúng với Python 2 hay Python 3? Hoặc cả hai?
alex

2

NB: Câu trả lời này đã lỗi thời đối với phiên bản mới nhất của python 3, nhưng ở đây là phiên bản cũ hơn. Để biết thêm thông tin, hãy đọc các bình luận và https://www.python.org/dev/peps/pep-0420/


Về cơ bản, mọi thư mục có mã python mà bạn muốn thêm vào syspath đều cần tệp __init__.py. Các tệp __init__.py này có thể trống.


Theo tôi hiểu, đây không còn là trường hợp nữa, thư mục giờ trở thành "không gian tên".
Aaron Hall

@AaronHall thú vị, nguồn nào?
don.joey

1
Hãy thử điều này để làm bằng chứng: python -c "from pathlib import Path; Path('ns').mkdir(); Path('ns/mod.py').write_text('''print('mod.py')'''); import ns.mod; from shutil import rmtree; rmtree('ns')"đây cũng là một số tài liệu liên quan, PEP 420, mô tả việc bổ sung ngữ nghĩa gói không gian tên
Aaron Hall
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.