2011-08-13 8 views
48

Trong khi câu hỏi này có phần phụ trợ python, câu hỏi là không gắn với chính python, mà là về cơ chế mở rộng và cách đăng ký/tra cứu bổ sung.Thực hiện thay thế các điểm nhập (mở rộng) python/setuptools trong các ngôn ngữ/ứng dụng khác

Trong python, khái niệm về điểm nhập đã được giới thiệu bởi setuptools và được gắn với siêu dữ liệu của bản phân phối python đã cài đặt (được gọi là gói trong hệ thống đóng gói khác). Theo hiểu biết của tôi, một trong những tính năng được cung cấp bởi entrypoints là cho phép ứng dụng xác định vị trí nơi người khác có thể đặt mọi thứ vào, vì vậy bất kỳ ứng dụng nào muốn sử dụng điểm vào đều có thể nhận danh sách các lớp/chức năng đã đăng ký ở đó . Hãy lấy một ví dụ:

  • Foo xác định điểm nhập "entrypoint1" và tìm các plugin được đăng ký dưới tên này.
  • Thanh ghi có thể gọi (Bar.callable) trên điểm nhập "entrypoint1".
  • Bất kỳ tập lệnh python nào cũng có thể liệt kê Bar.callable là một trong các cuộc gọi có đăng ký cho "entrypoint1".

Với công cụ cài đặt, ứng dụng đăng ký các điểm nhập liên quan đến thời gian cài đặt và thông tin được lưu trữ trong siêu dữ liệu liên quan đến bao bì, phụ thuộc của nó và một số siêu dữ liệu khác về bao bì).

Tôi có cảm giác rằng siêu dữ liệu đóng gói không phải là nơi thích hợp để lưu trữ loại thông tin này, vì tôi không hiểu tại sao thông tin này được gắn với bao bì.

Tôi rất tò mò muốn biết về các điểm nhập/mở rộng/tính năng bổ sung như vậy trong các ngôn ngữ khác và đặc biệt nếu khái niệm được gắn với siêu dữ liệu và bao bì hay không. Và câu hỏi đặt ra là…

Bạn có ví dụ tôi nên xem xét không? Bạn có thể giải thích tại sao các lựa chọn thiết kế đã được thực hiện theo cách đó?

Bạn có thể xem các cách khác nhau để xử lý sự cố này không? Bạn có biết vấn đề này đã được giải quyết như thế nào trong các công cụ khác nhau không? Nhược điểm và lợi thế của việc thực hiện python hiện tại so với những người khác là gì?


Những gì tôi đã tìm thấy cho đến nay

tôi đã tìm thấy trong các dự án khác nhau, một cách để tạo ra và phân phối "plugins", được đặc biệt là chăm sóc về "làm thế nào chúng tôi làm plugin ".

Ví dụ: libpeas (khung plugin gobject) xác định một tập hợp các cách để mở rộng hành vi mặc định bằng cách chỉ định plugin. Trong khi điều này là thú vị, tôi chỉ quan tâm đến việc "đăng ký và tìm kiếm" (và cuối cùng tải) một phần của nó.

Dưới đây là một số kết quả của tôi cho đến nay:

Libpeas định nghĩa its own metadata file (* .plugin), trong đó lưu trữ thông tin về loại của callable (nó có thể có các plugin khác nhau trong các ngôn ngữ khác nhau). Thông tin chính ở đây là tên của module cần tải.

Maven có a design document chứa thông tin về cách nội dung được quản lý tại đó. Maven quản lý các plugin với các phụ thuộc và siêu dữ liệu của chúng để có vẻ như đây là một nơi thú vị để tìm kiếm how they implemented things.

Như được chỉ định trong tài liệu của họ, maven plugins are using annotations (@goal) trên các lớp, sau đó được sử dụng để tìm tất cả các plugin được đăng ký với một số @goal cụ thể. Mặc dù cách tiếp cận này có thể có trong các ngôn ngữ tĩnh, nhưng nó không phải là ngôn ngữ thông dịch vì chúng tôi chỉ biết tất cả các lớp/cuộc gọi có thể có tại một thời điểm nhất định có thể thay đổi.

Sử dụng Mercurial a central configuration file (~/.hgrc), có thể tìm thấy ánh xạ tên của plugin cho đường dẫn.


Vài suy nghĩ nhiều

Trong khi đó không phải là một câu trả lời cho câu hỏi này, nó cũng là thú vị cần lưu ý cách setuptools điểm nhập được thực hiện, và làm thế nào họ so sánh về mặt hiệu suất, với những người lanh lợi .

Khi bạn yêu cầu một điểm nhập cụ thể với các công cụ thiết lập, all the metadata are read at run time and a list is built that way. Điều này có nghĩa là việc đọc này có thể mất chút thời gian nếu bạn có nhiều bản phân phối python trên đường dẫn của mình. Mercurial ở phía bên kia hardcode thông tin này vào một tệp duy nhất, có nghĩa là bạn phải chỉ định đường dẫn đầy đủ đến có thể gọi của bạn ở đó, sau đó cuộc gọi đã đăng ký không bị "phát hiện" nhưng "đọc" trực tiếp từ tệp cấu hình. Điều này cho phép cấu hình hạt mịn hơn trên những gì nên có sẵn và những gì không nên và có vẻ nhanh hơn. Ở phía bên kia, vì đường dẫn python có thể được thay đổi trong thời gian chạy, điều này có nghĩa là các cuộc gọi được cung cấp theo cách như vậy sẽ phải được kiểm tra trên đường dẫn để biết liệu chúng có được trả về hay không trong mọi tình huống. .


Tại sao entrypoints đang gắn liền với bao bì

Nó cũng là thú vị để hiểu tại sao điểm nhập được gắn với bao bì trong setuptools. Lý do chính là nó có vẻ hữu ích mà các bản phân phối python có thể đăng ký một phần của bản thân như mở rộng một điểm vào lúc cài đặt: sau đó cài đặt cũng có nghĩa là đăng ký các điểm nhập: không cần thêm một bước đăng ký.

Trong khi điều này hoạt động khá tốt trong phần lớn trường hợp (khi phân phối python thực sự được cài đặt), không khi chúng chưa được cài đặt hoặc không được đóng gói. Nói cách khác, từ những gì tôi hiểu, bạn không thể đăng ký một điểm vào lúc chạy, mà không có tệp .egg-info.

+6

Tôi cũng rất muốn biết. Các điểm nhập cảnh được canh tác ở những vị trí vượt quá phạm vi siêu dữ liệu đóng gói, ví dụ: giám sát viên sử dụng chúng trong nhiều định nghĩa tập tin conf của nó: http: //supervisord.org/configuration.html#rpcinterface-x-section-values ​​... cho những thứ như vậy, thật tuyệt khi không phải phụ thuộc vào ' các tập tin setup.py' và tương tự. – fish2000

Trả lời

0

Khi bạn bắt đầu nói về thực hiện/xử lý ngôn ngữ lập trình, có thể đáng lưu ý rằng gần đây gcc cũng đã mua được plugin capabilities.

0

Trong trăn, có "PYTHONPATH" là biến môi trường, xác định một địa điểm từ nơi "nhập" sẽ xem xét các đoạn mã.

Nếu bạn có một

PYTHONPATH=/home/user/tests 

tất cả subdirs trong

/home/user/tests 

có riêng tập tin

__init__.py 

của họ, danh sách các module có thể được tìm thấy ở đó.

Ví dụ: trong

/home/user/tests/__init__.py 

bạn có

__all__ = ["computeSomething", "computeSomthingElse"] 

đề cập đến các tập tin hiện có:

/home/user/tests/computeSomething.py 
/home/user/tests/computeSomethingElse.py 

sau đó, trong python, bạn có thể ngay lập tức

import computeSomethingElse 

hoặc

from computeSomethingElse import myObjectFromSomethingElse. 

Tôi hy vọng điều này sẽ giúp.

+0

Nó không trả lời thực sự cho (các) câu hỏi – Kartoch

1

là một trong những ý tưởng có thể, bạn có thể xem khái niệm OSGi, được sử dụng để quản lý hệ thống plugin của Eclipse. Nó có thể là quá mức cần thiết cho trường hợp cụ thể của bạn, nhưng chắc chắn là nguồn cảm hứng.