2016-12-18 14 views
7

Tôi đang sử dụng Python 3.5 cùng với Mypy để có một số kiểm tra tĩnh cơ bản cho tập lệnh của tôi. Gần đây tôi đã tái cấu trúc một số phương thức để trả về OrderedDict, nhưng chạy vào "loại 'đối tượng không phải là subscriptable" lỗi, khi tôi cố gắng sử dụng chú thích trả về với các loại khóa và giá trị được chỉ định.Làm cách nào để chỉ định các loại OrderedDict K, V cho chú thích Mypy type?

Giảm dụ:

#!/usr/bin/env python3.5 

from collections import OrderedDict 

# this works 
def foo() -> OrderedDict: 
    result = OrderedDict() # type: OrderedDict[str, int] 
    result['foo'] = 123 
    return result 

# this doesn't 
def foo2() -> OrderedDict[str, int]: 
    result = OrderedDict() # type: OrderedDict[str, int] 
    result['foo'] = 123 
    return result 

print(foo()) 

Và đây là kết quả trăn khi nó được chạy: Tuy nhiên

Traceback (most recent call last): 
    File "./foo.py", line 12, in <module> 
    def foo2() -> OrderedDict[str, int]: 
TypeError: 'type' object is not subscriptable 

Mypy không có vấn đề với các loại chú thích trong bình luận và trong thực tế sẽ cảnh báo nếu tôi cố gắng để làm result[123] = 123.

Điều gì gây ra điều này?

+1

Nó hoạt động bây giờ (mypy phiên bản 0,501). – max

Trả lời

5

Không có vấn đề gì trong mypy (ít nhất, không phải trong 0.501). Nhưng có sự cố với Python 3.6.0. xem xét như sau:

from collections import OrderedDict 
from typing import Dict 

def foo() -> Dict[str, int]: 
    result: OrderedDict[str, int] = OrderedDict() 
    result['two'] = 2 
    return result 

Mã này sẽ làm hài lòng cả mypy (0,501) và Python (3.6.0). Tuy nhiên, nếu bạn thay thế Dict bằng OrderedDict, thì mypy sẽ vẫn vui, nhưng việc thực thi nó sẽ chết với TypeError: 'type' object is not subscriptable. Một điều thú vị là trình thông dịch Python chết khi nhìn thấy một số chỉ số OrderedDict trong chữ ký hàm, nhưng rất vui khi chấp nhận nó trong một chú thích kiểu biến.

Ở mức nào, giải pháp của tôi cho việc này là sử dụng Dict thay vì OrderedDict trong chữ ký hàm (và thêm nhận xét rằng điều này sẽ được sửa nếu/khi trình thông dịch Python biết cách chấp nhận chữ ký chính xác).

+1

Vâng, tôi đã kết thúc bằng cách sử dụng cùng một cách giải quyết trong mã của riêng tôi. – Xarn

1

gì bạn cũng có thể thử sử dụng MutableMapping (như trong trả lời này: https://stackoverflow.com/a/44167921/1386610)

from collections import OrderedDict 
from typing import Dict 

def foo() -> MutableMapping[str, int]: 
    result = OrderedDict() # type: MutableMapping[str, int] 
    result['foo'] = 123 
    return result 
Các vấn đề liên quan