Sys.path của Python được khởi tạo từ đâu?


111

Sys.path của Python được khởi tạo từ đâu?

UPD : Python đang thêm một số đường dẫn trước khi tham chiếu đến PYTHONPATH:

    >>> import sys
    >>> from pprint import pprint as p
    >>> p(sys.path)
    ['',
     'C:\\Python25\\lib\\site-packages\\setuptools-0.6c9-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\orbited-0.7.8-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\morbid-0.8.6.1-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\demjson-1.4-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\stomper-0.2.2-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\uuid-1.30-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\stompservice-0.1.0-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\cherrypy-3.0.1-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\pyorbited-0.2.2-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\flup-1.0.1-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\wsgilog-0.1-py2.5.egg',
     'c:\\testdir',
     'C:\\Windows\\system32\\python25.zip',
     'C:\\Python25\\DLLs',
     'C:\\Python25\\lib',
     'C:\\Python25\\lib\\plat-win',
     'C:\\Python25\\lib\\lib-tk',
     'C:\\Python25',
     'C:\\Python25\\lib\\site-packages',
     'C:\\Python25\\lib\\site-packages\\PIL',
     'C:\\Python25\\lib\\site-packages\\win32',
     'C:\\Python25\\lib\\site-packages\\win32\\lib',
     'C:\\Python25\\lib\\site-packages\\Pythonwin']

PYTHONPATH của tôi là:

    PYTHONPATH=c:\testdir

Tôi tự hỏi những con đường trước khi những con đường của PYTHONPATH đến từ đâu?

Câu trả lời:


49

"Được khởi tạo từ biến môi trường PYTHONPATH, cộng với một mặc định phụ thuộc vào cài đặt"

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


7
Tôi đoán họ đến từ các module trang web: docs.python.org/library/site.html
ashcatch

20
Mô-đun trang web tải và phân tích cú pháp nội dung của bất kỳ tệp .pth nào trong thư mục gói trang của bạn. Các tệp .pth này chứa các bổ sung cho PYTHONPATH của bạn
HỎI

77

Python thực sự cố gắng thiết lập một cách thông minh sys.path. Làm thế nào nó được thiết lập có thể trở nên thực sự phức tạp . Các hướng dẫn sau đây là một phần nào-không đầy đủ, dẫn hơi-sai, nhưng hy vọng-hữu ích tưới xuống cho hàng ngũ quân đội và file python lập trình viên về những gì sẽ xảy ra khi con số python ra những gì để sử dụng như là giá trị ban đầu của sys.path, sys.executable, sys.exec_prefix, và sys.prefixtrên một cài đặt python bình thường .

Đầu tiên, python làm hết sức mình để tìm ra vị trí thực tế của nó trên hệ thống tệp dựa trên những gì hệ điều hành nói với nó. Nếu hệ điều hành chỉ cho biết "python" đang chạy, nó sẽ tự tìm thấy nó trong $ PATH. Nó giải quyết bất kỳ liên kết tượng trưng nào. Khi nó đã thực hiện xong việc này, đường dẫn của tệp thực thi mà nó tìm thấy được sử dụng làm giá trị cho sys.executable, không có ifs, ands hoặc buts.

Tiếp theo, nó xác định các giá trị ban đầu cho sys.exec_prefixsys.prefix.

Nếu có một tệp được gọi pyvenv.cfgtrong cùng một thư mục với sys.executablehoặc một thư mục lên, python sẽ xem xét nó. Các hệ điều hành khác nhau làm những việc khác nhau với tệp này.

Một trong những giá trị trong tệp cấu hình này mà python tìm kiếm là tùy chọn cấu hình home = <DIRECTORY>. Python sẽ sử dụng thư mục này thay vì thư mục chứa sys.executable khi nó tự động đặt giá trị ban đầu sys.prefixsau này. Nếu applocal = truecài đặt xuất hiện trong pyvenv.cfgtệp trên Windows, nhưng không xuất hiện trong home = <DIRECTORY>cài đặt, thì cài đặt đó sys.prefixsẽ được đặt thành thư mục chứa sys.executable.

Tiếp theo, PYTHONHOMEbiến môi trường được kiểm tra. Trên Linux và Mac, sys.prefixsys.exec_prefixđược đặt thành PYTHONHOMEbiến môi trường, nếu nó tồn tại, sẽ thay thế mọi home = <DIRECTORY>cài đặt trong pyvenv.cfg. Trên Windows, sys.prefixsys.exec_prefixđược đặt thành PYTHONHOMEbiến môi trường, nếu nó tồn tại, trừ khi có một home = <DIRECTORY>cài đặt pyvenv.cfg, được sử dụng thay thế.

Nếu không, chúng sys.prefixsys.exec_prefixđược tìm thấy bằng cách đi ngược lại từ vị trí của sys.executable, hoặc homethư mục được cung cấp bởi pyvenv.cfgnếu có.

Nếu tệp lib/python<version>/dyn-loadđược tìm thấy trong thư mục đó hoặc bất kỳ thư mục mẹ nào của nó, thì thư mục đó được đặt thành sys.exec_prefixtrên Linux hoặc Mac. Nếu tệp lib/python<version>/os.pyđược tìm thấy trong thư mục hoặc bất kỳ thư mục con nào của nó, thì thư mục đó được đặt thành sys.prefixtrên Linux, Mac và Windows, sys.exec_prefixđược đặt thành giá trị giống như sys.prefixtrên Windows. Toàn bộ bước này bị bỏ qua trên Windows nếu applocal = trueđược đặt. Thư mục của sys.executableđược sử dụng hoặc, nếu homeđược đặt trong pyvenv.cfg, được sử dụng thay thế cho giá trị ban đầu của sys.prefix.

Nếu nó không thể tìm thấy các tệp "mốc" này hoặc sys.prefixvẫn chưa được tìm thấy, thì python sẽ đặt sys.prefixthành giá trị "dự phòng". Ví dụ, Linux và Mac sử dụng các giá trị mặc định được biên dịch trước làm giá trị của sys.prefixsys.exec_prefix. Windows sẽ đợi cho đến khi sys.pathđược tìm hiểu đầy đủ để đặt giá trị dự phòng cho sys.prefix.

Sau đó, (những gì bạn đã chờ đợi,) python xác định các giá trị ban đầu được chứa trong đó sys.path.

  1. Thư mục của tập lệnh mà python đang thực thi được thêm vào sys.path. Trên Windows, đây luôn là chuỗi trống, lệnh này yêu cầu python sử dụng đường dẫn đầy đủ nơi tập lệnh được đặt thay thế.
  2. Nội dung của biến môi trường PYTHONPATH, nếu được đặt, sẽ được thêm vào sys.path, trừ khi bạn đang sử dụng Windows và applocalđược đặt thành true trong pyvenv.cfg.
  3. Đường dẫn tệp zip, <prefix>/lib/python35.ziptrên Linux / Mac và os.path.join(os.dirname(sys.executable), "python.zip")Windows, được thêm vào sys.path.
  4. Nếu trên Windows và không applocal = trueđược đặt trong pyvenv.cfg, thì nội dung của các khóa con của khóa đăng ký HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\sẽ được thêm vào, nếu có.
  5. Nếu trên Windows và không có applocal = trueđược thiết lập pyvenv.cfgsys.prefixkhông thể tìm thấy, thì nội dung cốt lõi của khóa đăng ký HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\sẽ được thêm vào, nếu nó tồn tại;
  6. Nếu trên Windows và không applocal = trueđược đặt trong pyvenv.cfg, thì nội dung của các khóa con của khóa đăng ký HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\sẽ được thêm vào, nếu có.
  7. Nếu trên Windows và không có applocal = trueđược thiết lập pyvenv.cfgsys.prefixkhông thể tìm thấy, thì nội dung cốt lõi của khóa đăng ký HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\sẽ được thêm vào, nếu nó tồn tại;
  8. Nếu trên Windows và PYTHONPATH không được đặt, không tìm thấy tiền tố và không có khóa đăng ký nào thì giá trị thời gian biên dịch tương đối của PYTHONPATH sẽ được thêm vào; nếu không, bước này bị bỏ qua.
  9. Các đường dẫn trong macro thời gian biên dịch PYTHONPATH được thêm vào liên quan đến được tìm thấy động sys.prefix.
  10. Trên Mac và Linux, giá trị của sys.exec_prefixđược thêm vào. Trên Windows, thư mục đã được sử dụng (hoặc sẽ được sử dụng) để tìm kiếm động sys.prefixsẽ được thêm vào.

Ở giai đoạn này trên Windows, nếu không tìm thấy tiền tố nào, thì python sẽ cố gắng xác định nó bằng cách tìm kiếm tất cả các thư mục trong đó sys.pathcho các tệp mốc, như nó đã cố gắng thực hiện với thư mục sys.executabletrước đó, cho đến khi tìm thấy thứ gì đó. Nếu không, sys.prefixđược để trống.

Cuối cùng, sau tất cả những điều này, Python tải sitemô-đun, mô-đun này bổ sung thêm nhiều thứ cho sys.path:

Nó bắt đầu bằng cách xây dựng tối đa bốn thư mục từ phần đầu và phần đuôi. Đối với phần đầu, nó sử dụng sys.prefixsys.exec_prefix; đầu trống được bỏ qua. Đối với phần đuôi, nó sử dụng chuỗi trống và sau đó lib/site-packages(trên Windows) hoặc lib/pythonX.Y/site-packages và sau đó lib/site-python(trên Unix và Macintosh). Đối với mỗi kết hợp head-tail riêng biệt, nó sẽ xem liệu nó có tham chiếu đến một thư mục hiện có hay không và nếu có, thêm nó vào sys.path và cũng kiểm tra đường dẫn mới được thêm vào cho các tệp cấu hình.


1
Bất chấp những gì tài liệu của nó nói, sys.executablecó thể là một liên kết tượng trưng hoặc thực sự nó có thể là bất cứ thứ gì nếu argv[0]chứa dấu gạch chéo. Đường dẫn thực sự đến tệp thực thi (từ execv(path, argv)cuộc gọi) không được sử dụng.
jfs

1
Liên quan đến điểm đầu tiên của bạn sys.pathtrên windows 10: Tôi luôn nhận được đường dẫn đầy đủ của tập lệnh dir dưới dạng sys.path [0] (không phải cwd ''). Bạn sẽ có thể thực hiện một cái gì đó nhưpython some\other\path\than\cwd\main.py
ford04

Tôi đồng ý với @ ford04. Điểm 1 không chính xác: Trên Windows, thư mục của tập lệnh được thêm vào sys.path, không phải là một đường dẫn trống, cũng không phải cwd. Đây là trong các bản cài đặt Python 3.x khác nhau.
gwideman

1
Wow, điều này thật tuyệt vời! Tôi đã xem khoảng 10 câu hỏi và câu trả lời khác trước khi tình cờ nhận ra điều này, "sự thật", mặc dù bạn đang khiêm tốn thừa nhận rằng bạn không hoàn toàn có tất cả.
Mike Williamson

1
Tôi sẽ thêm các tệp có liên quan đó ở dạng site-packages.pth.egg-linkhậu tố.
florisla
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.