2015-09-25 30 views
7

Tôi đang chơi xung quanh một chút với mô-đun gợi ý/gõ mới với python3.5 cố gắng tìm cách xác nhận nếu loại được gợi ý bằng loại biến thực tế và bắt gặp một thứ khiến tôi ngạc nhiên.Tại sao việc khôi phục ([1, 2, 3], Danh sách [str]) được đánh giá là đúng?

>>> from typing import List 
>>> someList = [1, 2, 3] 
>>> isinstance(someList, List[str]) 
True 

Tiếp tục tìm kiếm của tôi cho việc tìm kiếm một cách để so sánh một biến để nó ám chỉ loại I cũng đã thử điều này:

>>> anotherList = ["foo", "bar"] 
>>> type(anotherList) is List[str] 
False 

có bất cứ ai có thể giải thích tại sao chính xác đánh giá lại cựu True?

Và tiếp tục trở đi, có cách nào để kiểm tra xem loại biến có bằng loại từ mô-đun nhập không?

+2

Vâng, một điều, 'loại (x) là' và 'isinstance (x, a)' chắc chắn không giống nhau. Một đối tượng có thể là một thể hiện của nhiều kiểu (với một hệ thống phân cấp thừa kế), nhưng 'type (x)' chỉ cung cấp cho bạn loại duy nhất cụ thể nhất của nó. – BrenBarn

+0

Yup, tôi biết điều đó sau khi đã thực hiện một số thử nghiệm với nó. Vẫn cảm thấy như bao gồm nó trong câu hỏi của tôi vì nó thường được đưa ra như là go-to khi yêu cầu bất cứ điều gì về so sánh loại trong Python. – McMuffinton

+0

Loại '' '(['foo', 'bar']) == Danh sách [str]' '' đánh giá là gì? –

Trả lời

4

isinstance không thực hiện kiểm tra loại PEP 484 thực. The documentation ghi chú này trong đi qua:

Nói chung, isinstance()issubclass() không nên được sử dụng với các loại.

Các typing module, cũng như collections.abcabc module nó dựa trên, sử dụng rộng __instancecheck__ and __subclasscheck__ ma thuật để làm cho isinstanceissubclass cư xử một cách hợp lý. Nhưng họ không làm đủ để hỗ trợ cho trường hợp của bạn. Cũng không phải là mục tiêu của họ để hỗ trợ nó.

có cách nào để kiểm tra xem loại của biến có bằng loại từ mô-đun nhập không?

Bạn không tìm kiếm loại bình đẳng. Như bạn đã lưu ý, loại [1, 2, 3]list, không phải là bằng đến List[str], cũng không phải là List[int]. Bạn đang tìm kiếm loại kiểm tra, điều này phức tạp hơn nhiều.

Hãy xem xét điều này:

def my_function(): 
    # ... 1000 lines of very complicated code ... 

print(isinstance(my_function, Callable[[], int])) 

gì bạn mong chờ chương trình này để in? Bạn không thể mong đợi isinstance để khai thác thành my_function khi chạy và suy ra rằng nó luôn trả về int. Điều này là không khả thi trong Python. Bạn cần trình kiểm tra loại thời gian "biên dịch" có quyền truy cập vào cấu trúc của my_function hoặc chú thích loại rõ ràng hoặc có khả năng nhất — cả hai.

+0

Cảm ơn rất nhiều câu trả lời rõ ràng và súc tích của bạn.Tôi chắc chắn hiểu tại sao bạn không thể mong đợi một hàm để tìm ra nếu một hàm khác luôn trả về một biến của một kiểu nào đó, nhưng tôi tưởng tượng rằng nó sẽ bằng cách nào đó có thể _check_ nếu một biến duy nhất tương ứng với một kiểu đến từ mô-đun đánh máy. Mặc dù có thể yêu cầu kiểm tra thủ công xem mỗi mục trong danh sách có thuộc loại nào đó trong các trường hợp giao dịch với các danh sách lớn hoặc các loại lồng nhau hay không (Danh sách [Dict [str, List [int]]) mất quá nhiều thời gian để có thể thực hiện được. Tuy nhiên, một lần nữa, cảm ơn một bó cho câu trả lời của bạn! – McMuffinton

+1

@McMuffinton Điểm của tôi là 'my_function' là" một biến duy nhất "cũng như' someList' của bạn. Nếu bạn không mong muốn suy ra loại 'my_function' trong thời gian chạy, thì cũng không có lý do gì để mong đợi rằng' someList'. –

+0

_are_ 'isinstance' và' issubclass' phải làm gì sau đó? – brandonscript

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