Tôi không thể thấy các mô-đun khác có sẵn thông qua tập lệnh python đã biên dịch. Làm cách nào tôi có thể thay đổi quy trình sau để chấp nhận các mô-đun dựa trên venv hoặc mô-đun toàn cầu?
nhịp độ:
$ python3 -m venv đôi khi
$ cd đôi khi
$ .bin/kích hoạt
(đôi khi) $ pip3 cài đặt PyCrypto Cython
Tập lệnh cơ bản, sử dụng các mô-đun không chuẩn
tiền điện tử
:
# xin chào.py
từ nhập khẩu Crypto.Cipher AES
import base64
obj = AES.new('Đây là key123', AES.MODE_CBC, 'Đây là IV456')
msg = "Câu trả lời là không"
bản mã = obj.encrypt(tin nhắn)
in (tin nhắn)
in(base64.b64encode(bản mã))
(đôi khi) $ python3 hello.py
Câu trả lời là không
b'1oONZCFWVJKqYEEF4JuL8Q=='
Biên dịch:
(đôi khi) $ cython -3 --embed hello.py
(đôi khi) $ gcc -Os -I /usr/include/python3.5m -o hello hello.c -lpython3.5m -lpthread -lm -lutil -ldl
(đôi khi) $ $ ./xin chào
Traceback (most recent call last):
Tệp "hello.py", dòng 1, trong init hello
từ nhập khẩu Crypto.Cipher AES
Lỗi nhập: Không có mô-đun nào có tên 'Crypto'
Tôi không nghĩ việc sử dụng venv từ tập lệnh biên dịch nhúng cython là một vấn đề: tập lệnh hoạt động ở nơi khác trong hệ thống mà không có venv (tức là.
python3 -c 'từ Crypto.Cipher nhập AES'
sẽ không thất bại).
Quá trình hoạt động tốt nếu không:
(đôi khi) $ echo 'print("hello world")' > hello2.py
(đôi khi) $ cython -3 --embed hello2.py
(đôi khi) $ gcc -Os -I /usr/include/python3.5m -o hello2 hello2.c -lpython3.5m -lpthread -lm -lutil -ldl
(đôi khi) $ ./hello2
xin chào thế giới
hệ thống:
(đôi khi) $ python3 --version
Python 3.5.2
(đôi khi) $ pip3 đóng băng
Cython==0,29,11
tài nguyên pkg==0.0.0
pycrypto==2.6.1
(đôi khi) $ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS"
Nói chung, trình thông dịch Python không "độc lập" và để chạy, nó cần có thư viện chuẩn (ví dụ:ctypes
(biên soạn) hoặcsite.py
(đã giải thích)) cũng như đường dẫn đến các gói trang web khác (ví dụ:có khối u
) phải được thiết lập.
Mặc dù có thể bằng cách đóng băng mô-đun py và đặt tất cả các phần mở rộng c (xem ví dụ:bài SO này) vào tệp thực thi được tạo để làm cho trình chèn Python hoàn toàn độc lập, nhưng việc cung cấp cài đặt cần thiết cho trình chèn được nhúng sẽ dễ dàng hơn.
Đôi khi không tìm thấy gói mô-đun/trang web tiêu chuẩn ngay lập tức: trình thông dịch phải được trợ giúp bằng cách đặt đường dẫn Python, tức là bằng cách cài đặt<..>/sometest/lib/python3.5/site-packages
中添加đôi khi
(là thư mục gốc của môi trường ảosys.path
) để giúp người phiên dịch. Lập trình trong tệp pyx hoặc bằng cách cài đặt trước khi bắt đầuPYTHONPATH
-biến môi trường được thiết lập.
Đọc tiếp để biết thêm chi tiết và giải pháp thay thế.
Câu trả lời này áp dụng cho Linux và Python3 (Python 3.7), ý tưởng cơ bản giống với Windows/MacOS, nhưng một số chi tiết có thể khác nhau.
vì sử dụngvenv
, vì vậy chúng tôi có các phương án sau để giải quyết vấn đề này:
Lập trình ở vị trí tệp pyx<..>/sometest/lib/python3.5/site-packages
(đôi khi
là thư mục gốc của môi trường ảo) được thêm vàosys.path
hoặc bằng cách cài đặt trước khi khởi chạyPYTHONPATH
-biến môi trường.
Đặt tệp thực thi với python nhúng vàođôi khi
trong một thư mục con (ví dụ:cái thùng
hoặc tạo thư mục của riêng bạn).
sử dụngảo hóa
thay thếvenv
.
Lưu ý: Đối với các tệp thực thi có python nhúng, nó không hoạt động bất kể môi trường ảo có được kích hoạt hay không (hoặc môi trường ảo nào).
Tại sao cách trên giải quyết được vấn đề trong trường hợp của bạn?
Vấn đề là, trình thông dịch Python (được nhúng) cần tìm ra những điều sau:
Các thư mục/tệp độc lập với nền tảng, ví dụ:os.py
,argparse.py
(chủ yếu là *.py/*.pyc). được chosys.prefix
, trình thông dịch có thể tìm ra nơi để tìm thấy chúng (tức là trongtiền tố/lib/pythonX.Y
ở giữa).
Các thư mục/tệp dành riêng cho nền tảng, chẳng hạn như thư viện dùng chung. được chosys.exec_prefix
, trình thông dịch có thể tìm ra nơi để tìm chúng (ví dụ: các thư viện dùng chung có thể được tìm thấy trongexec_prefix/lib/pythonX.Y/lib-dynload
được tìm thấy trong).
thực hiệntìm thấy ở đâyKhi đó, thuật toán có thểPy_Khởi tạo
và thực hiện tìm kiếm. Khi các thư mục này được tìm thấy, bạn có thể xây dựngsys.path
.
Tuy nhiên, sử dụngvenv
khi nào sẽ có mộtpyvenv.cfg
tài liệubên cạnh exe hoặc trong thư mục mẹ, tệp này đảm bảo tìm thấy Python-Home chính xác - điểm khởi đầu tốt là trong tệp nàytrang chủ
键。
nếu không được đặtPy_NoSiteFlag
,NhưngPy_Khởi tạo
sẽ sử dụngsite.py
(Nó có thể được tìm thấy thông qua trình thông dịch vìsys.prefix
được biết đến) hay chính xác hơntrang web.main ()
để thêm các gói trang web của môi trường ảo vàosys.path
. Khi làm điều này,site.py
Tìm thấypyvenv.cfg
và phân tích nó. Tuy nhiên, địa phương sẽ chỉgói trang web
Thêm vào đường dẫn python:
Nếu một tệp có tên "pyvenv.cfg" nằm ở một trong các thư mục trên
sys.executable, sys.prefix và sys.exec_prefix được đặt thành
thư mục và cũng kiểm tra xem nó có chứa các gói trang web hay không (sys.base_prefix
và sys.base_exec_prefix sẽ luôn như vậy
cài đặt Python).
Trong trường hợp của bạn,pyvenv.cfg
Không có trong thư mục trên, nhưng giống như exe - vì vậy các gói trang web cục bộ cài đặt thư viện qua pip không được bao gồm. Gói trang web toàn cầu không được bao gồm vìpyvenv.cfg
có chìa khóainclude-system-site-packages = false
. Do đó, các gói trang web không được phép và không thể tìm thấy các thư viện đã cài đặt.
Tuy nhiên, việc di chuyển exe xuống một thư mục sẽ khiến gói trang cục bộ được đưa vào đường dẫn.
Có những trường hợp có thể xảy ra khác, điều quan trọng nhất là vị trí của tệp thực thi chứ không phải môi trường nào được kích hoạt.
Trả lời: Tệp thực thi ở đâu đó, nhưng không phải trong môi trường ảo
Phương pháp phỏng đoán tìm kiếm này ít nhiều đáng tin cậy đối với các trình thông dịch python đã cài đặt, nhưng có thể hữu ích cho các trình thông dịch nhúng hoặc môi trường ảo (để biết thêm thông tin, hãy xemvấn đề này).
Nếu sử dụng thông thườngcài đặt thích hợp
hoặc phương pháp tương tự, nó sẽ được tìm thấy (do4. bước) và trình thông dịch nhúng sẽ sử dụng cài đặt hệ thống.
Tuy nhiên, nếu tệp được di chuyển hoặc python được xây dựng từ nguồn và không được cài đặt, trình điều khiển nhúng sẽ không khởi động được:
Không thể tìm thấy các thư viện độc lập với nền tảng
Không thể tìm thấy thư viện phụ thuộc nền tảng
Hãy cân nhắc việc đặt $PYTHONHOME thành [:]
Lỗi Python nghiêm trọng: initfsencoding: không thể tải codec hệ thống tệp
ModuleNotFoundError: Không có mô-đun nào có tên 'mã hóa'
trong trường hợp này,
Py_SetPythonHome
hoặc đặt biến môi trường
$PYTHONHOME
là một giải pháp khả thi.
B: Có thể thực thi trong môi trường ảo, được tạo bởi virtualenv
Giả sử môi trường ảo và python nhúng là cùng một phiên bản Python (nếu không chúng ta gặp tình huống trên), exe, exe nhúng sẽ sử dụng gói cục bộ. quy cho
quy tắc này, thuật toán tìm kiếm địa chỉ sẽ luôn tìm thấy địa chỉ nhà địa phương:
Bước 3. Cố gắng tìm tiền tố và exec_prefix liên quan đến argv0_path, quay lại đường dẫn cho đến khi hết. Đây là bước phổ biến nhất để thành công. Xin lưu ý rằng nếu tiền tố và exec_prefix là
Sự khác biệt là exec_prefix có nhiều khả năng được tìm thấy hơn;
exec_prefix là thư mục con của tiền tố và có thể tìm thấy cả hai.
trong trường hợp này,
argv0_path
là đường dẫn đến exe (không có
pyvenv.cfg
tài liệu! ),Và
"cột mốc"(lib/python$VERSION/os.py và lib/python$VERSION/lib-dynload) sẽ được tìm thấy vì chúng được trình bày dưới dạng liên kết tượng trưng trong trang chủ cục bộ phía trên exe.
C: Trong
venv
Hai thư mục thực thi bên trong môi trường
Trong các trường hợp sau đây, ở
venv
Di chuyển xuống hai thư mục trong môi trường thay vì một (nơi nó hoạt động): Trường hợp A: Không đọc trong khi tìm kiếm thư mục chính (quá xa)
pyvenv.cfg
tệp, môi trường 'venv` thiếu liên kết tượng trưng 'mốc' trỏ đến liên kết sau (gói phụ chỉ có sẵn cục bộ), bước 3 sẽ chỉ thất bại với
4. bướcĐó là hy vọng.
Kết luận: Python nhúng sẽ không hoạt động nếu không cài đặt đúng Python, trừ khi có các khả năng khác:
Các tệp cần thiết được đóng gói bên cạnh hoặc phía trên tệp thực thi được nhúng
lib\pythonX.Y\*
trong (và không có xung quanh
pyvenv.cfg
sẽ gây nhầm lẫn cho việc tìm kiếm).
hoặc
pyvenv.cfg
Được sử dụng để trỏ trình thông dịch đến vị trí chính xác.
Tôi là một lập trình viên xuất sắc, rất giỏi!