2016-09-11 16 views
6

Tôi vừa mới cải thiện vùng phủ sóng thử nghiệm cho một library có để hỗ trợ lát và tôi đã nhận thấy rằng lát có thể chứa các loại phi thể thiếu:Tại sao các loại nội trang không tách rời được cho phép trong các lát trăn?

>>> slice(1, "2", 3.0) 
slice(1, '2', 3.0) 
>>> sl = slice(1, "2", 3.0) 
>>> [1,2,3][sl] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: slice indices must be integers or None or have an __index__ method 

này chỉ có thể là nền tĩnh đánh máy của tôi nhưng có vẻ như lạ với tôi rằng các loại nội trang mà không có __index__ có thể được chuyển vào đây mà không cần TypeError. Tại sao cái này rất? Tôi có thể giả định rằng các loại tùy ý được cho phép để hỗ trợ nhập vịt cho các loại thực hiện __index__? Việc thiếu kiểm tra loại có phải do lý do hiệu suất đối với các trường hợp thường được sử dụng nhất không?

Trước khi PEP 357 là lát trong ví dụ không hợp lệ?

+0

Cú pháp cú pháp với phao có thể mô tả hiệu quả một hộp giới hạn trong không gian n chiều, có thể thuận tiện trong một số trường hợp. Một loại tùy chỉnh có thể chấp nhận các lát như vậy. – Kevin

+0

Đó là một trường hợp sử dụng thực sự thú vị cho một phao mà tôi đã không nghĩ đến. Tại sao dây được phép mặc dù? – shuttle87

+1

Bạn cũng có thể sử dụng [Dấu ba chấm] (http://stackoverflow.com/questions/772124/what-does-the-python-ellipsis-object-do) trong lát. –

Trả lời

2

Tôi có được giả định rằng các loại tùy ý được phép để hỗ trợ nhập vịt cho các loại thực hiện __index__?

Không có lý do thực tế nào là tại sao bạn nên hạn chế các loại được truyền khi khởi tạo slice đối tượng. Chính xác như đã nêu trong hợp lý cho PEP 357, numpy và các loại số mà nó sử dụng không thể kế thừa từ đối tượng để kiểm tra nghiêm ngặt issubclass loại được chuyển sẽ làm cho chúng không sử dụng được dưới dạng giá trị chỉ mục. Vì vậy, gõ vịt được sử dụng, nếu nó xác định phương pháp thích hợp (__index__), nó có thể sử dụng được.

Ngoài ra hãy lưu ý rằng đây (sự hiện diện của __index__) được thi hành chỉ khi áp dụng các lát (như bạn đã thấy, các TypeError được nuôi nấng trong __getitem__, tức là list_subscript) hoạt động khi PySlice_GetIndicesEx được gọi là để thử và nhận các giá trị bạn thông qua.

Các slice objects initializer làm cho không có phân biệt đối xử về những gì loại nó chấp nhận, tất cả PyObject 's có thể áp dụng như có thể được nhìn thấy từ chữ ký của mình:

PyObject * 
PySlice_New(PyObject *start, PyObject *stop, PyObject *step) 
{ 
    /* rest omitted */ 

Trước PEP 357 là lát trong ví dụ này không hợp lệ?

tôi chỉ xây dựng một phiên bản 2.4 của Python và thử nghiệm nó (PEP 357 xuất hiện trong 2.5 nếu tôi không nhầm), một lần nữa việc kiểm tra nếu đối số là số không được thực hiện trong quá trình khởi nhưng khi __getitem__ được gọi; điều duy nhất mà khác là thông điệp ngoại lệ mà không thực hiện bất kỳ thông báo về __index__ dunder (mà sau đó rõ ràng là không tồn tại):

Python 2.4 (#1, Sep 11 2016, 18:13:11) 
[GCC 5.4.0 20160609] on linux4 
Type "help", "copyright", "credits" or "license" for more information. 
>>> s = slice(0, Ellipsis) 
>>> [1, 2, 3][s] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in ? 
TypeError: slice indices must be integers 
4

thư viện của bên thứ ba có thể muốn thực hiện cắt cho các đối tượng của mình và không có lý do gì để ngôn ngữ cốt lõi hạn chế các thư viện của bên thứ ba đó chỉ sử dụng các số nguyên hoặc các đối tượng giống số nguyên (nghĩa là các đối tượng có kiểu cung cấp phương thức __index__) trong các lát của chúng. Dưới đây là hai ví dụ đáng chú ý của các gói sử dụng phi số nguyên trong cắt: trong NumPy, một số đối tượng chấp nhận một bước phức tạp, ví dụ:

>>> import numpy 
>>> numpy.mgrid[0:2:5j] 
array([ 0. , 0.5, 1. , 1.5, 2. ]) 

Và trong Pandas, bạn có thể cắt một Series hoặc Dataframe đối tượng bằng nhãn. Nhãn đó có thể là một chuỗi, hoặc một đối tượng datetime (ví dụ).

>>> import pandas 
>>> s = pandas.Series(range(4), index=['a', 'b', 'c', 'd']) 
>>> s['b':'d'] 
b 1 
c 2 
d 3 
dtype: int64 

Vì vậy, sẽ không có ý nghĩa khi ngôn ngữ cốt lõi đưa ra ngoại lệ khi xây dựng một lát chứa số nguyên không phải là số nguyên; điều đó sẽ phá vỡ các thư viện trên. Thay vào đó, thao tác cắt thực tế sẽ tăng ngoại lệ nếu các thành phần slice (bắt đầu, dừng, bước) không thuộc loại thích hợp.

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