2010-06-29 48 views
55

Tôi vừa tham gia một dự án với một cơ sở mã hiện có khá lớn. Chúng tôi phát triển trong linux và không sử dụng và IDE. Chúng tôi chạy qua dòng lệnh. Tôi đang cố gắng tìm ra cách để có được python để tìm kiếm con đường bên phải khi tôi chạy các mô-đun dự án. Ví dụ, khi tôi chạy một cái gì đó như:Mở rộng Đường dẫn Tìm kiếm Python đến Nguồn Khác

python someprojectfile.py 

tôi nhận được

ImportError: no module named core.'somemodule' 

tôi có được điều này cho tất cả các hàng nhập khẩu của tôi để tôi giả sử nó là một vấn đề với đường dẫn.

TLDR:

Làm thế nào để có được Python để tìm kiếm ~/codez/project/ và tất cả các file và thư mục tập tin * py trong báo cáo nhập khẩu.

Trả lời

95

Có một vài cách có thể để làm điều này:

  • Đặt biến môi trường PYTHONPATH vào một danh sách thư đại tràng-tách các thư mục để tìm kiếm các module nhập khẩu.
  • Trong chương trình của bạn, sử dụng sys.path.append('/path/to/search') để thêm tên thư mục bạn muốn Python tìm kiếm các mô-đun đã nhập. sys.path chỉ là danh sách các thư mục tìm kiếm Python mỗi khi nó được yêu cầu nhập một mô-đun, và bạn có thể thay đổi nó khi cần thiết (mặc dù tôi sẽ không khuyên bạn nên loại bỏ bất kỳ thư mục chuẩn nào!). Bất kỳ thư mục nào bạn đưa vào biến môi trường PYTHONPATH sẽ được chèn vào sys.path khi Python khởi động.
  • Sử dụng site.addsitedir để thêm thư mục vào sys.path. Sự khác biệt giữa việc này và chỉ đơn thuần là khi bạn sử dụng addsitedir, nó cũng tìm kiếm các tệp .pth trong thư mục đó và sử dụng chúng để có thể thêm các thư mục bổ sung vào sys.path dựa trên nội dung của tệp. Xem tài liệu để biết thêm chi tiết.

Điều nào bạn muốn sử dụng tùy thuộc vào tình huống của bạn. Hãy nhớ rằng khi bạn phân phối dự án của mình cho những người dùng khác, họ thường cài đặt nó theo cách mà các tệp mã Python sẽ được tự động phát hiện bởi trình nhập khẩu của Python (tức là các gói thường được cài đặt trong thư mục site-packages), vì vậy nếu bạn gây rối với sys.path mã của bạn, điều đó có thể không cần thiết và thậm chí có thể có tác dụng phụ khi mã đó chạy trên một máy tính khác. Để phát triển, tôi sẽ mạo hiểm đoán rằng thiết lập PYTHONPATH thường là cách tốt nhất để đi.

Tuy nhiên, khi bạn đang sử dụng một cái gì đó mà chỉ chạy trên máy tính của bạn (hoặc khi bạn có các thiết lập không chuẩn, ví dụ như đôi khi trong khung ứng dụng web), nó không phải là hoàn toàn không phổ biến để làm điều gì đó như

from os.path import dirname 
sys.path.append(dirname(__file__)) 
+0

Vì vậy, nếu tôi muốn nói 15 thư mục con, tôi sẽ phải thêm từng thư mục riêng lẻ? – themaestro

+0

và bạn có thể đưa ra ví dụ về đối số dòng lệnh để thay đổi PYTHONPATH không? – themaestro

+2

Để đặt 'PYTHONPATH': trong' .bashrc' hoặc bất kỳ tệp khởi động nào mà shell của bạn sử dụng (nếu nó không phải Bash), hãy viết 'export PYTHONPATH = $ PYTHONPATH: $ HOME/codez/project'. Nhưng nếu bạn có một loạt các thư mục con, tôi sẽ tạo một tệp '.pth' và sử dụng' site.addsitedir'. Bạn có thể tạo một mô-đun 'sitecustomize' có thể gọi hàm cho bạn; thử đặt nó ở '~/.local/lib/python2.6/sitecustomize.py' (thay thế phiên bản Python của bạn) để hy vọng sẽ được nhập tự động. –

9

Bạn cũng nên đọc về các gói python tại đây: http://docs.python.org/tutorial/modules.html.

Từ ví dụ của bạn, tôi đoán bạn thực sự có một gói hàng tại ~/codez/project. Các tập tin __init__.py trong một thư mục python ánh xạ một thư mục vào một không gian tên. Nếu các thư mục con của bạn đều có tệp __init__.py thì bạn chỉ cần thêm thư mục cơ sở vào PYTHONPATH của mình.Ví dụ:

PYTHONPATH = $ PYTHONPATH: $ HOME/adaifotis/dự án

Ngoài thử nghiệm biến môi trường PYTHONPATH của bạn, như David giải thích, bạn có thể kiểm tra nó trong python như thế này:

$ python 
>>> import project      # should work if PYTHONPATH set 
>>> import sys 
>>> for line in sys.path: print line # print current python path 

...

+0

Bạn có thể muốn đặt '__init __. Py' của bạn trong các dấu backticks để làm cho nó rõ ràng bạn thực sự có nghĩa là' __init __. Py', trái ngược với 'init.py'. Chỉ để tránh những người mới khó hiểu. :) – antred

2

tôi đọc câu hỏi này tìm kiếm một câu trả lời, và không thích ai trong số họ.

Vì vậy, tôi đã viết một giải pháp nhanh chóng và bẩn. Chỉ cần đặt một nơi nào đó trên sys.path của bạn, và nó sẽ thêm bất kỳ thư mục dưới folder (từ thư mục làm việc hiện hành), hoặc dưới abspath:

#using.py 

import sys, os.path 

def all_from(folder='', abspath=None): 
    """add all dirs under `folder` to sys.path if any .py files are found. 
    Use an abspath if you'd rather do it that way. 

    Uses the current working directory as the location of using.py. 
    Keep in mind that os.walk goes *all the way* down the directory tree. 
    With that, try not to use this on something too close to '/' 

    """ 
    add = set(sys.path) 
    if abspath is None: 
     cwd = os.path.abspath(os.path.curdir) 
     abspath = os.path.join(cwd, folder) 
    for root, dirs, files in os.walk(abspath): 
     for f in files: 
      if f[-3:] in '.py': 
       add.add(root) 
       break 
    for i in add: sys.path.append(i) 

>>> import using, sys, pprint 
>>> using.all_from('py') #if in ~, /home/user/py/ 
>>> pprint.pprint(sys.path) 
[ 
#that was easy 
] 

Và tôi thích nó vì tôi có thể có một thư mục cho một số các công cụ ngẫu nhiên và không có chúng là một phần của gói hoặc bất kỳ thứ gì và vẫn có quyền truy cập vào một số (hoặc tất cả) của chúng trong một vài dòng mã.

1

Cách dễ nhất tôi tìm thấy là tạo tệp "any_name.pth" và đặt tệp đó vào thư mục "\ Lib \ site-packages" của bạn. Bạn nên tìm thư mục đó bất cứ nơi nào python được cài đặt.

Trong tệp đó, hãy đặt danh sách các thư mục nơi bạn muốn giữ mô-đun để nhập. Ví dụ, tạo ra một dòng trong tập tin đó như thế này:

C: \ Users \ ví dụ ... \ dụ

Bạn sẽ có thể cho biết nó hoạt động bằng cách chạy này trong python:

import sys 
for line in sys: print line 

Bạn sẽ thấy thư mục của mình được in ra, trong số các thư mục khác từ nơi bạn cũng có thể nhập. Bây giờ bạn có thể nhập tệp "mymodule.py" nằm trong thư mục đó dễ dàng như:

import mymodule 

Điều này sẽ không nhập thư mục con. Để làm điều đó bạn có thể tưởng tượng việc tạo một tập lệnh python để tạo một tệp .pth chứa tất cả các thư mục con của một thư mục mà bạn định nghĩa. Có nó chạy lúc khởi động có lẽ.

1

Tôi biết chủ đề này hơi cũ, nhưng phải mất một thời gian để có được trái tim của điều này, vì vậy tôi muốn chia sẻ.

Trong dự án của mình, tôi có kịch bản chính trong thư mục mẹ, và để phân biệt các mô-đun, tôi đặt tất cả các mô-đun hỗ trợ trong thư mục con được gọi là "mô-đun". Trong kịch bản chính của tôi, tôi nhập khẩu các mô-đun như thế này (đối với một module gọi là report.py):

từ báo cáo nhập khẩu modules.report, reportError

Nếu tôi gọi kịch bản chính của tôi, công trình này. Tuy nhiên, tôi muốn kiểm tra mỗi mô-đun bằng cách bao gồm một main() trong mỗi, và gọi nhau trực tiếp, như:

python module \ report.py

Bây giờ Python phàn nàn rằng nó không thể tìm thấy "một module được gọi là mô-đun ". Chìa khóa ở đây là, theo mặc định, Python bao gồm thư mục của tập lệnh trong đường dẫn tìm kiếm của nó, NHƯNG KHÔNG CWD. Vì vậy, những gì lỗi này nói, thực sự, là "Tôi không thể tìm thấy một thư mục con module".Điều này là do không có thư mục con "modules" từ thư mục chứa module report.py.

tôi thấy rằng các giải pháp thú vị nhất cho điều này là để phụ thêm CWD trong đường dẫn tìm kiếm bằng cách bao gồm Python này ở phía trên: ("")

import sys

sys.path.append

Bây giờ Python tìm kiếm CWD (thư mục hiện tại), tìm thư mục con "mô-đun" và tất cả đều tốt.

Các vấn đề liên quan