Trải nghiệm về Python PEP-302 của Python Nhập móc mới [đóng]


40

Tôi là một trong những nhà phát triển của Ruby (CRuby). Chúng tôi đang làm việc trên phiên bản Ruby 2.0 (dự kiến ​​phát hành 2012 / Feb).

Python có "PEP302: Móc nhập mới" (2003):

PEP này đề xuất thêm một bộ móc nhập mới cung cấp khả năng tùy chỉnh tốt hơn cho cơ chế nhập Python. Trái ngược với hook nhập hiện tại , hook kiểu mới có thể được đưa vào lược đồ hiện có, cho phép kiểm soát chi tiết hơn về cách tìm thấy các mô-đun và cách chúng được tải.

Chúng tôi đang xem xét giới thiệu một tính năng tương tự PEP302 vào Ruby 2.0 (CRuby 2.0). Tôi muốn đưa ra một đề nghị có thể thuyết phục Matz. Hiện tại, CRuby có thể tải tập lệnh từ chỉ các hệ thống tệp theo cách tiêu chuẩn.

Nếu bạn có bất kỳ kinh nghiệm hoặc cân nhắc về PEP 302, vui lòng chia sẻ.

Thí dụ:

  1. Đó là một thông số tuyệt vời. Không cần phải thay đổi nó.
  2. Nó gần như là tốt, nhưng nó có vấn đề này ...
  3. Nếu tôi có thể quay lại năm 2003, thì tôi sẽ thay đổi thông số thành ...

6
Wow, chính anh chàng YARV, xin chào và chào mừng các lập trình viên! ;) Trên Stack Exchange, chúng tôi thực sự không thích thảo luận kết thúc mở, thay vào đó chúng tôi thích giải quyết các vấn đề cụ thể (đọc nhanh câu hỏi thường gặp của chúng tôi ) - điều mà tôi đoán là tại sao câu hỏi của bạn bị đóng trên Stack Overflow và nó đã có bỏ phiếu chặt chẽ ở đây. Bạn nên thử làm điều này cụ thể hơn một chút - bạn có lo ngại cụ thể về PEP 302 đã thúc đẩy câu hỏi này không?
yannis

4
Cảm ơn bạn đã bình luận của bạn, Yannis. Tôi nghĩ rằng tôi muốn thảo luận về "kiến trúc phần mềm". PEP302 dường như là khuôn khổ mạnh mẽ và chung để mở rộng trình tải của riêng họ trên trình thông dịch python. Tuy nhiên, tính năng mạnh mẽ có rủi ro như lạm dụng (tạo mã ma thuật), ngăn chặn tối ưu hóa trình thông dịch. Vì vậy, tôi muốn biết khung mở rộng này có ngọt hay không cho người dùng python nhà phát triển trình thông dịch. Tôi tin rằng nghiên cứu lịch sử sẽ giúp tôi tạo ra thông số tốt về Ruby 2.0.
Koichi Sasada

Cảm ơn bạn sửa đổi câu hỏi của tôi khá. Và tôi xin lỗi nếu câu hỏi này không thích hợp hơn.
Koichi Sasada

Đây là một ví dụ tuyệt vời về cách một câu hỏi xuất hiện, trên bề mặt, thất bại trong bài kiểm tra "thăm dò ý kiến" của chúng tôi, dù sao cũng có thể chứng minh là có giá trị đáng kinh ngạc.
Ross Patterson

Câu trả lời:


47

Tôi là người duy trì mô-đun runpy của Python và là một trong những người duy trì hệ thống nhập khẩu hiện tại. Mặc dù hệ thống nhập khẩu của chúng tôi rất linh hoạt, tôi khuyên bạn không nên áp dụng bán buôn mà không thực hiện một số điều chỉnh - do lo ngại về khả năng tương thích ngược, có rất nhiều điều khó xử hơn những gì họ cần phải làm.

Một điều đau lòng với PEP 302 trong Python là chúng tôi mất bao lâu để chuyển đổi hệ thống nhập khẩu lõi sang sử dụng nó. Để tốt hơn cho một thập kỷ, bất kỳ ai làm bất cứ điều gì phức tạp với móc nhập đã bị mắc kẹt khi thực hiện hai phần: một bộ xử lý bộ tải tuân thủ PEP 302 (chẳng hạn như nhập zip) và xử lý thứ hai cơ chế nhập dựa trên hệ thống tệp tiêu chuẩn. Chỉ trong phiên bản 3.3 sắp tới, việc xử lý các trình tải PEP 302 cũng sẽ đảm nhiệm việc xử lý các mô-đun được nhập thông qua cơ chế nhập hệ thống tệp tiêu chuẩn. Cố gắng không lặp lại sai lầm đó nếu bạn có thể tránh được.

PEP 420 (được triển khai cho Python 3.3) thực hiện một số bổ sung cho giao thức để cho phép các nhà nhập khẩu đóng góp các phần vào các gói không gian tên. Nó cũng sửa một vấn đề đặt tên trong định nghĩa API Finder (thay thế hiệu quả "find_module" được đặt tên sai bằng "find_loader" chính xác hơn). Điều này hy vọng tất cả sẽ được ghi lại rõ ràng hơn trong thông số ngôn ngữ vào thời điểm 3.3rc1 xuất hiện trong một vài tuần.

Một vấn đề đáng chú ý khác là cách tiếp cận được ghi lại cụ thể trong PEP 302 có quá nhiều trạng thái toàn cầu. Đừng theo chúng tôi theo con đường đó - hãy thử đóng gói trạng thái trong một mô hình đối tượng mạch lạc hơn để dễ dàng nhập một cách có chọn lọc các mô-đun khác (mô-đun mở rộng C là nguyên nhân giúp cho việc đóng gói hoàn toàn có hiệu quả, nhưng thậm chí ở một mức độ đóng gói nào đó có thể hữu ích).

PEP 406 (http://www.python.org/dev/peps/pep-0406/) thảo luận về một sự tiến hóa tương thích ngược có thể có của phương pháp của Python với việc đóng gói trạng thái được cải thiện. Nếu bạn có một mô hình trạng thái được đóng gói ngay từ đầu, thì bạn có thể xác định API phù hợp và tránh việc các nhà nhập khẩu và trình tải truy cập trạng thái toàn cầu (thay vào đó được chuyển tham chiếu đến công cụ hoạt động).

Một phần còn thiếu trong PEP 302 là khả năng yêu cầu nhà nhập khẩu cho một trình vòng lặp qua các mô-đun được cung cấp bởi nhà nhập khẩu đó (điều này là cần thiết cho những thứ như tiện ích đóng băng và tiện ích tài liệu tự động trích xuất tài liệu). Vì nó là vô cùng hữu ích, bạn có thể muốn được tốt hơn tiêu chuẩn hóa nó từ get đi: http://docs.python.org/dev/library/pkgutil#pkgutil.iter_modules (chúng tôi sẽ có lẽ cuối cùng nâng cao này cho một người chính thức quy định API trong Python 3.4)

Và nhận xét cuối cùng của tôi là bạn nên xem xét kỹ sự phân chia trách nhiệm giữa hệ thống nhập khẩu và các đối tượng bộ nạp. Cụ thể, hãy xem xét tách API "load_module" thành các bước "init_module" và "exec_module" riêng biệt. Điều đó sẽ cho phép bạn giảm thiểu mức độ mà trình tải cần tương tác trực tiếp với trạng thái nhập.

PEP 302 và importlib là điểm khởi đầu tuyệt vời cho một hệ thống nhập khẩu linh hoạt hơn, nhưng chắc chắn có những sai lầm chúng tôi đã mắc phải đáng để tránh.


1
Họ đang không khá xong, nhưng một dự thảo ban đầu của tài liệu hệ thống nhập khẩu đầy đủ có thể được tìm thấy tại docs.python.org/dev/reference/import
ncoghlan

1
python.org/dev/peps/pep-0451 là bản cập nhật cho hệ thống nhập khẩu của Python cho Python 3.4 nhằm giải quyết nhiều ý kiến ​​từ Brett và tôi ở đây.
ncoghlan

28

Bên cạnh ncoghlan Tôi là người duy trì hệ thống nhập khẩu khác của Python và là tác giả của triển khai hiện tại của nó, importlib (http://docs.python.org/dev/py3k/l Library / imllib.html). Mọi thứ Nick nói tôi đồng ý, vì vậy tôi chỉ muốn thêm một số thông tin.

Đầu tiên, đừng phụ thuộc quá nhiều vào PEP 302 trực tiếp mà thay vào đó hãy nhìn vào những gì importlib cung cấp về các lớp cơ sở trừu tượng, v.v. Để những thứ tương thích ngược phải tương thích với PEP 302, nhưng tôi phải thêm một số API riêng để hoàn thành việc hỗ trợ cho sự linh hoạt thực sự.

Một điểm quan trọng khác là bạn đang cung cấp cho các nhà phát triển hai phần linh hoạt. Một là khả năng lưu trữ mã theo cách khác với chỉ trực tiếp trên hệ thống tệp dưới dạng các tệp riêng lẻ (tôi gọi đây là back-end lưu trữ để nhập), ví dụ: điều này cho phép mã sống trong tệp zip, cơ sở dữ liệu sqlite, v.v. . Hỗ trợ khác là cho phép kiểm soát mã trước hoặc sau quá trình theo một cách nào đó, ví dụ Quixote (https://www.mems-exchange.org/software/quixote/) và việc sử dụng thay thế chuỗi ký tự chuỗi không được gán cho một biến sẽ dễ dàng hơn nhiều để hỗ trợ.

Trong khi cái sau hiếm khi cần thiết, cái trước là nơi bạn phải lo lắng về hỗ trợ. Và đây là nơi bạn thực sự xác định lại các API tương tác hệ thống tệp. Vì một số người cần tài sản được lưu trữ dưới dạng tệp với mã của họ, bạn cần cung cấp một cách tốt để đọc tệp, khám phá tệp, v.v. Chúng tôi vẫn cần triển khai phần API để khám phá tệp dữ liệu nào có sẵn, liệt kê chúng, v.v. .

Nhưng sau đó, bạn cũng có nhu cầu về API dành riêng cho mã. Như Nick đã đề cập, cuối cùng bạn cần API để khám phá những mô-đun mà gói chứa, v.v. không phải là tệp cụ thể. Có sự đối ngẫu kỳ lạ của việc có API để xử lý các mô-đun nơi bạn đã trích xuất khái niệm tệp, nhưng sau đó bạn cần phải cung cấp API để truy cập dữ liệu tài sản giống như tệp. Và ngay khi bạn cố gắng thực hiện cái này liên quan đến cái kia để tránh trùng lặp, vùng nước trở nên rất âm u (tức là mọi người cuối cùng dựa vào cấu trúc đường dẫn tệp dự kiến, v.v. mà không chú ý đến thực tế đường dẫn có thể không phải là một con đường thực sự bởi vì nó dành cho mã zip chứa mã chứ không chỉ là tệp). IOW cuối cùng bạn sẽ phải thực hiện hai API tương tự, nhưng về lâu dài bạn sẽ có lợi hơn cho nó.

Như Nick đã nói, giải pháp của chúng tôi là một điểm khởi đầu tốt, nhưng đó không phải là cách tôi sẽ làm ngay hôm nay nếu tôi thiết kế API từ đầu.


-1

PEP 302 cho phép bạn nối vào cơ chế nhập Python, nghĩa là bạn có thể nhập mã từ các nguồn khác như cơ sở dữ liệu, tệp zip, v.v.

Trong quá trình nhập Python, có một lịch sử phức tạp lâu dài sẽ chỉ được đơn giản hóa bằng cách giới thiệu triển khai nhập Python.

Tôi nên khuyên suy nghĩ lâu và khó về các trường hợp góc. Sau đó, bạn có khả năng để có được một thực hiện hữu ích.

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.