mypy: Tại sao hoàng tử là một tiểu loại của phao nổi?


8

Tại sao "mypy" coi "int" là một kiểu con của "float"? Một kiểu con sẽ hỗ trợ tất cả các phương thức của siêu kiểu của nó, nhưng "float" có các phương thức mà "int" không hỗ trợ:

kiểm tra:

def f(x : float) -> bool:
    return x.is_integer()

print(f(123.0))
print(f(123))

Trình kiểm tra kiểu tĩnh chấp nhận chuyển một đối số "int" cho tham số "float":

(3.8.1) myhost% mypy test.py
Success: no issues found in 1 source file

Nhưng điều này không đảm bảo, rằng không có lỗi trong thời gian chạy:

(3.8.1) myhost% python test.py
True
Traceback (most recent call last):
  File "test.py", line 5, in <module>
    print(f(123))
  File "test.py", line 2, in f
    return x.is_integer()
AttributeError: 'int' object has no attribute 'is_integer'

bởi vì "float" có các phương thức bổ sung, mà "int" không có.


5
Ôi chà, điều này có vẻ tệ với tôi, đây là lời giải thích: mypy.readthedocs.io/en/latest/duck_type_compabilities.html
juanpa.arrivillaga

2
@BlackFrog không, không thể.
juanpa.arrivillaga

3
@BlackFrog int Không thể vừa trong một chiếc phao. Python intkhông phải là máy ints. (Dù sao, tôi không chắc nó có liên quan đến việc kiểm tra kiểu như thế nào, điều này không thực sự liên quan đến các kiểu biểu diễn trong thời gian chạy.)
chepner

1
Trừ khi tôi thiếu một cái gì đó, lý do sử dụng gõ vịt intfloatdường như hoàn toàn bỏ qua thực tế là cả hai loại đều có phương thức, hoặc ít nhất là các phương pháp khác ngoài __add__et al.
chepner

1
@StefanPochmann có, nhưng như được hiển thị ở đây, từ một hệ thống kiểu POV, thì không
juanpa.arrivillaga

Câu trả lời:


1

'Tại sao "mypy" coi "int" là một kiểu con của "float"?'

Bởi vì tính thực tiễn cho đến nay đã được coi là đánh bại sự tinh khiết ở đây. Điều này không có nghĩa là người ta không thể đề xuất rằng việc gõ xác định loại vô hướng sẽ bao gồm int và float mà chỉ có giá trị cho các phép toán số học.

Lưu ý rằng int / int đã được thay đổi trong 3.0 sao cho float (int / int) == float (int) / float (int), để làm cho số học int và float phù hợp với các giá trị int và float bằng nhau.

Cũng lưu ý rằng việc vượt qua kiểm tra loại không có nghĩa là không có lỗi thời gian chạy: chia cho 0 và tràn vẫn có thể, cũng như nhiều cách khác.


-1

Như @ juanpa.arrivillaga đã chỉ ra, lời giải thích có trên https://mypy.readthedocs.io/en/latest/duck_type_compabilities.html .

Một kiểu con sẽ hỗ trợ tất cả các phương thức của siêu kiểu của nó, nhưng "float" có các phương thức, mà "int" không hỗ trợ

intkhông một subtype của float, vì vậy nó không phải phương pháp hỗ trợ float.

Cơ chế này tốt vì truyền các giá trị nguyên không nên gây ra lỗi, trừ khi bạn thực sự muốn chúng như trong ví dụ của bạn. Bạn rõ ràng đã cố gắng sử dụng một phương pháp không tồn tại. Trong các tình huống phổ biến, chúng tôi chỉ thực hiện các phép toán số học trên các số, vì vậy một vấn đề hiếm khi tồn tại và bạn luôn có thể tránh nó bằng cách thêm vào .0như bạn đã viết.

Đây là một hành vi phổ biến trong hầu hết các ngôn ngữ để cho rằng đó intlà trường hợp đặc biệt float, xem xét ví dụ C ++ intđể floatchuyển đổi ngầm định.


Thành thật mà nói, "bạn luôn có thể tránh nó bằng cách sử dụng đúng loại" không phải là một lập luận thuyết phục đối với tôi đối với một trình kiểm tra loại bị sai.
juanpa.arrivillaga

Toàn bộ điểm đánh máy tĩnh là chính xác để tránh sử dụng một phương thức không được xác định cho loại. Phần đầu tiên của câu trả lời là tốt; tiếp tục giải thích lý do tại sao không có nhược điểm chỉ là làm mọi người bất đồng.
chepner

Tôi đã không downvote, cho hồ sơ.
juanpa.arrivillaga
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.