2012-04-21 24 views
7

Tôi hiện đang trải qua một khóa học compsci cơ bản. Chúng tôi sử dụng in của Python rất nhiều. Tôi tò mò làm thế nào nó được thực hiện, những gì mã mà quyền hạn in trông giống như.Làm cách nào để bạn điều tra việc triển khai thực hiện các phương thức tích hợp sẵn của python?

Tôi có thể nghĩ cách thực hiện để thực hiện điều này, nhưng điều tôi đã học được sau khi chuyển sang một vài bài tập về nhà là cách làm việc của tôi thường khá khủng khiếp và không hiệu quả. muốn bắt đầu điều tra mã 'tốt'.

+0

'in' là một ví dụ không may - nó không phải là một hàm duy nhất (trừ khi bạn đếm bộ thông dịch bytecode bên dưới, nhưng mọi thứ lộn xộn ở đó và có ít nhưng chính sách cấp thấp), đó là một phương thức của toán hạng bên phải. Để làm cho mọi thứ trở nên tồi tệ hơn, có một trường hợp đặc biệt mà * không * có một cài đặt mặc định, được chôn ở đâu đó ở độ sâu của trình thông dịch bytecode. – delnan

+1

@ delnan thực sự nó không quá tệ, tôi đã tìm kiếm nó khi tôi mở rộng câu trả lời của tôi, và nó chỉ chống lại một hàm trong abstract.c, vì vậy bạn không thực sự phải nhìn vào trình thông dịch bytecode để xem việc thực hiện của. –

+0

@ DevinJeanpierre Cảm ơn, tôi không quá quen thuộc với những người bên trong như vậy - tôi chỉ biết 'in' có hướng dẫn bytecode riêng của mình, nên đã đoán họ sử dụng lại mã để thực hiện C-API. – delnan

Trả lời

10

Những điều về chức năng được xây dựng trong và các loại và các nhà khai thác và vân vân là chúng không thực hiện bằng Python. Thay vào đó, chúng được thực hiện trong C, đó là một ngôn ngữ lập trình đau đớn và chi tiết hơn và sẽ không luôn luôn dịch tốt sang Python (thường là vì mọi thứ dễ dàng hơn trong Python một cách dễ dàng hơn.)

Với điều đó, bạn có thể điều tra tất cả việc triển khai trực tuyến của Python, thông qua public source repository của họ.

Việc triển khai cho in được phân tán - có một triển khai cho mỗi loại, cộng với triển khai tổng quát hơn gọi triển khai loại cụ thể (nhiều hơn về sau). Ví dụ: đối với danh sách, chúng tôi sẽ tìm kiếm việc triển khai danh sách. Trong cây nguồn Python, nguồn cho tất cả các đối tượng dựng sẵn nằm trong thư mục Objects. Trong thư mục đó, bạn sẽ tìm thấy listobject.c, trong đó có chứa thực hiện cho đối tượng danh sách và tất cả các phương thức của nó.

Trên kho lưu trữ tại thời điểm trả lời, nếu bạn nhìn vào line 393 bạn sẽ thấy việc triển khai toán tử trong (còn được gọi là phương thức __contains__, giải thích tên hàm). Nó khá đơn giản, chỉ lặp qua tất cả các phần tử của danh sách cho đến khi tìm thấy phần tử hoặc không có phần tử nào khác và trả về kết quả tìm kiếm. :)

Nếu nó giúp, bằng Python cách ngữ viết này sẽ là:

def __contains__(self, obj): 
    for item in self: 
     if item == obj: 
      return True 

    return False 

tôi đã nói trước rằng có một thực hiện tổng quát hơn.Điều đó có thể được nhìn thấy trong việc triển khai PySequence_Contains trong abstract.c. Nó cố gắng gọi phiên bản kiểu cụ thể, và nếu điều đó không thành công, hãy đặt chỗ cho việc lặp lại thông thường. Vòng lặp đó có những gì một Python thường xuyên cho vòng lặp trông giống như khi bạn viết nó trong C (bằng cách sử dụng Python C-API).

+0

C có đau không? Chỉ khi bạn không biết điều đó. –

+3

@Bryan, C nổi tiếng là đau đớn để gỡ lỗi. Nếu bạn không đồng ý với sự nổi tiếng, tốt. Tôi không có ý định bắt đầu một cuộc tranh cãi. (Để công bằng, C là dễ dàng hơn nhiều để gỡ lỗi một khi bạn tìm hiểu về Valgrind :) –

+0

Tôi biết C, và tôi biết Python, và C là đau đớn hơn. Không có Cuộc thi Python bị xáo trộn, mặc dù nó đã được đề xuất. – morningstar

0

Bạn có thể duyệt Python-Nguồn trực tuyến: http://hg.python.org/

Một khởi đầu tốt là clone kho bạn cần và sau đó sử dụng grep để tìm những thứ bạn cần.

2

Phương thức dựng sẵn của Python được viết bằng ngôn ngữ C - bạn có thể xem mã của chúng bằng cách tự mình kiểm tra mã nguồn của Python. Tuy nhiên, nếu bạn muốn xem xét việc thực hiện tương đương tất cả các phương thức trong Python, bạn có thể kiểm tra PyPy - có tính năng thực thi Python 100% được viết bằng Python và một tập con của nó (rpython).

Toán tử in gọi phương thức __contains__ trong đối tượng chuỗi - vì vậy bạn có thể kiểm tra việc triển khai chuỗi trong cả hai dự án - nhưng mã tìm kiếm thực tế sẽ được chôn sâu hơn.

Dưới đây là một số mã trong CPython cho nó, ví dụ:

http://hg.python.org/cpython/file/c310233b1d64/Objects/stringlib/fastsearch.h

+2

Đối số "PyPy is in Python" chỉ là một nửa của câu chuyện. Sự thật là: RPython trong thực tế khá khác với Python, và trình thông dịch Python của PyPy là một sự thực thi rất linh hoạt của một ngôn ngữ khá phức tạp. Nó được chia thành hàng trăm tệp, sử dụng rất nhiều hướng dẫn, có tất cả các logic phức tạp cho tất cả các trường hợp đặc biệt, có nhiều mã chỉ để tối ưu hóa và thường xuyên quay lại mã * rất * cấp thấp, bao gồm cả chữ C. đơn giản như nó có thể được, nhưng tôi sẽ không mong đợi hầu hết các sinh viên để quản lý nó. – delnan

6

Từ phần Data Model của Python Ngôn ngữ tham khảo:

Các nhà khai thác thử nghiệm thành viên (innot in) thường được thực hiện như một lặp thông qua một chuỗi. Tuy nhiên, đối tượng chứa có thể cung cấp phương thức đặc biệt sau đây với việc triển khai hiệu quả hơn, cũng không yêu cầu đối tượng phải là một chuỗi.

object.__contains__(self, item)

Được gọi để thực hiện các toán tử kiểm tra thành viên. Phải trả về true nếu mục là tự, sai khác. Đối với các đối tượng ánh xạ, điều này nên xem xét các khóa của ánh xạ chứ không phải các giá trị hoặc các cặp khóa mục .

Đối với các đối tượng không xác định __contains__(), kiểm tra thành viên đầu tiên cố gắng lặp qua __iter__(), sau đó trình tự cũ lặp giao thức qua __getitem__(), xem phần này trong ngôn ngữ tham khảo.

Vì vậy, theo mặc định, Python lặp qua chuỗi để thực hiện toán tử in. Nếu một đối tượng định nghĩa phương thức __contains__, Python sẽ sử dụng nó thay vì lặp lại. Vậy điều gì sẽ xảy ra trong phương pháp __contains__? Để biết chính xác, bạn sẽ phải duyệt the source. Nhưng tôi có thể cho bạn biết rằng danh sách của Python thực hiện __contains__ bằng cách sử dụng lặp lại. Từ điển và tập hợp Python được triển khai dưới dạng hash tables và do đó hỗ trợ kiểm tra thành viên nhanh hơn.

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