Kiểm tra Python Loại tùy chọn

Thường có những tình huống trong mã không tồn tại giá trị bắt buộc. Một cách điển hình để giải quyết vấn đề này là trả về

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
59 nhưng tùy chọn cung cấp cách rõ ràng hơn và tùy chọn. mô-đun py cung cấp triển khai tùy chọn dễ sử dụng

Cho đến bây giờ, chúng tôi hầu như chỉ giới hạn ở các loại tích hợp sẵn. Phần này giới thiệu một số loại bổ sung. Bạn có thể cần ít nhất một số trong số chúng để kiểm tra bất kỳ chương trình không tầm thường nào

các loại lớp

Mỗi lớp cũng là một loại hợp lệ. Bất kỳ trường hợp nào của một lớp con cũng tương thích với tất cả các lớp cha - theo đó mọi giá trị đều tương thích với loại [và tình cờ cũng là loại

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
1, được thảo luận bên dưới]. Mypy phân tích nội dung của các lớp để xác định phương thức và thuộc tính nào có sẵn trong các phiên bản. Ví dụ này sử dụng phân lớp

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]

Loại bất kỳ

Một giá trị với loại

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
1 được nhập động. Mypy không biết gì về các loại thời gian chạy có thể có của giá trị đó. Mọi hoạt động đều được phép trên giá trị và các hoạt động chỉ được kiểm tra khi chạy. Bạn có thể sử dụng
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
1 làm “cửa thoát hiểm” khi không thể sử dụng loại chính xác hơn vì lý do nào đó

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
1 tương thích với mọi loại khác và ngược lại. Bạn có thể tự do gán giá trị kiểu
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
1 cho một biến có kiểu chính xác hơn

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]

Các loại được khai báo [và được suy luận] bị bỏ qua [hoặc bị xóa] khi chạy. Về cơ bản, chúng được coi là nhận xét và do đó đoạn mã trên không tạo ra lỗi thời gian chạy, mặc dù

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
6 nhận giá trị
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
7 khi chương trình chạy, trong khi loại
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
6 được khai báo thực sự là
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
9. Bạn cần cẩn thận với các loại
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
1, vì chúng cho phép bạn nói dối mypy và điều này có thể dễ dàng che giấu lỗi

Nếu bạn không xác định giá trị trả về của hàm hoặc các loại đối số, những giá trị này sẽ được mặc định là

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
1

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
3

Bạn nên cung cấp cho một hàm được nhập tĩnh một kiểu trả về rõ ràng

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 ngay cả khi nó không trả về một giá trị, vì điều này cho phép mypy bắt thêm các lỗi kiểu

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
5

Nếu chúng ta đã sử dụng một kiểu trả về rõ ràng là

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42, mypy sẽ bắt lỗi

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...

Loại

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
1 được thảo luận chi tiết hơn trong phần

Ghi chú

Một hàm không có bất kỳ loại nào trong chữ ký được nhập động. Phần thân của hàm được nhập động không được kiểm tra tĩnh và các biến cục bộ có các loại

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
1 ngầm định. Điều này giúp di chuyển mã Python kế thừa sang mypy dễ dàng hơn, vì mypy sẽ không phàn nàn về các hàm được nhập động

các loại tuple

Loại

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
46 đại diện cho một bộ với các loại mục
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
47, …,
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
48

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
4

Một loại tuple của loại này có chính xác một số mục cụ thể [2 trong ví dụ trên]. Các bộ cũng có thể được sử dụng như các chuỗi có độ dài khác nhau, không thay đổi. Bạn có thể sử dụng loại _____149 [với ____ _ _ _250 theo nghĩa đen - đó là một phần của cú pháp] cho mục đích này. Thí dụ

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
5

Ghi chú

Thông thường, tốt hơn là sử dụng

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
51 thay vì
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
49, vì nó cũng tương thích với danh sách và các chuỗi không theo bộ khác

Ghi chú

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
54 có giá trị như một lớp cơ sở trong Python 3. 6 trở lên và luôn ở trong các tệp sơ khai. Trong các phiên bản Python cũ hơn, đôi khi bạn có thể khắc phục giới hạn này bằng cách sử dụng một bộ có tên làm lớp cơ sở [xem phần ]

Các loại có thể gọi được [và lambdas]

Bạn có thể chuyển các đối tượng hàm và các phương thức liên kết trong mã được nhập tĩnh. Loại hàm chấp nhận các đối số

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
55, …,
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
56 và trả về
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
57 là
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
58. Thí dụ

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
4

Bạn chỉ có thể có các đối số vị trí và chỉ những đối số không có giá trị mặc định, trong các loại có thể gọi được. Chúng bao gồm phần lớn việc sử dụng các loại có thể gọi được, nhưng đôi khi điều này không đủ. Mypy nhận ra một hình thức đặc biệt

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
59 [với một chữ
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
50] có thể được sử dụng trong các trường hợp ít điển hình hơn. Nó tương thích với các đối tượng có thể gọi tùy ý trả về một loại tương thích với
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
41, không phụ thuộc vào số lượng, loại hoặc loại đối số. Mypy cho phép bạn gọi các giá trị có thể gọi như vậy với các đối số tùy ý mà không cần kiểm tra – về mặt này, chúng được xử lý tương tự như chữ ký hàm
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
42. Thí dụ

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
9

Trong các tình huống cần các loại gọi lại chính xác hoặc phức tạp hơn, người ta có thể sử dụng linh hoạt. Lambdas cũng được hỗ trợ. Các loại giá trị trả về và đối số lambda không thể được đưa ra một cách rõ ràng;

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
0

Nếu bạn muốn đưa ra các loại đối số hoặc giá trị trả về một cách rõ ràng, hãy sử dụng một định nghĩa hàm thông thường, có lẽ là hàm lồng nhau

các loại công đoàn

Các hàm Python thường chấp nhận các giá trị thuộc hai hoặc nhiều loại khác nhau. Bạn có thể sử dụng để đại diện cho điều này, nhưng các loại kết hợp thường thuận tiện hơn

Sử dụng hàm tạo kiểu

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
43 để tạo kiểu kết hợp. Ví dụ: nếu một đối số có loại
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
44, thì cả số nguyên và chuỗi đều là giá trị đối số hợp lệ

Bạn có thể sử dụng séc để thu hẹp loại liên kết thành loại cụ thể hơn

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
0

Ghi chú

Các hoạt động chỉ hợp lệ cho các loại liên kết nếu chúng hợp lệ cho mọi mục liên kết. Đây là lý do tại sao thường cần sử dụng séc để thu hẹp loại kết hợp thành loại không kết hợp trước tiên. Điều này cũng có nghĩa là nên tránh các kiểu kết hợp làm kiểu trả về của hàm, vì người gọi có thể phải sử dụng trước khi thực hiện bất kỳ điều gì thú vị với giá trị

Các loại tùy chọn và loại Không có

Bạn có thể sử dụng công cụ sửa đổi loại để xác định một biến thể loại cho phép

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42, chẳng hạn như
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
90 [
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
91 là cách viết tắt ưa thích của
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
92]

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
1

Hầu hết các hoạt động sẽ không được phép trên

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 không được bảo vệ hoặc các giá trị

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
2

Thay vào đó, cần phải kiểm tra rõ ràng

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42. Mypy có khả năng suy luận kiểu mạnh mẽ cho phép bạn sử dụng các thành ngữ Python thông thường để bảo vệ chống lại các giá trị
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42. Ví dụ: mypy nhận ra
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
97 kiểm tra

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
3

Mypy sẽ suy ra loại

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
98 là
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
7 trong khối khác do kiểm tra đối với
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 trong điều kiện if

Các kiểm tra được hỗ trợ khác để bảo vệ chống lại giá trị

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 bao gồm
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
02,
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
03 và
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
04. Ngoài ra, mypy hiểu kiểm tra
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 trong các biểu thức logic

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
4

Đôi khi mypy không nhận ra rằng một giá trị không bao giờ là

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42. Điều này đáng chú ý xảy ra khi một thể hiện của lớp có thể tồn tại ở trạng thái được xác định một phần, trong đó một số thuộc tính được khởi tạo thành
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 trong quá trình xây dựng đối tượng, nhưng một phương thức giả định rằng thuộc tính đó không còn là
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42. Mypy sẽ phàn nàn về giá trị
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 có thể. Bạn có thể sử dụng
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
00 để giải quyết vấn đề này trong phương thức

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
5

Khi khởi tạo một biến là

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42,
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 thường là một giá trị giữ chỗ trống và giá trị thực có kiểu khác. Đây là lý do tại sao bạn cần chú thích một thuộc tính trong các trường hợp như lớp
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
03 ở trên

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
6

Điều này cũng hoạt động đối với các thuộc tính được xác định trong các phương thức

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
7

Đây không phải là vấn đề khi sử dụng chú thích biến, vì không cần giá trị ban đầu

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
8

Mypy thường sử dụng phép gán đầu tiên cho một biến để suy ra loại biến. Tuy nhiên, nếu bạn chỉ định cả giá trị

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 và giá trị không phải ____142 trong cùng một phạm vi, mypy thường có thể thực hiện đúng mà không cần chú thích

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
9

Sometimes you may get the error “Cannot determine type of ”. In this case you should add an explicit

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
06 annotation [or type comment].

Ghi chú

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 là loại chỉ có một giá trị,
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42.
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 cũng được sử dụng làm kiểu trả về cho các hàm không trả về giá trị, tôi. e. các hàm hoàn toàn trả về
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42

Ghi chú

Trình thông dịch Python nội bộ sử dụng tên

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
11 cho loại
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42, nhưng
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 luôn được sử dụng trong chú thích loại. Cái sau ngắn hơn và đọc tốt hơn. [
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
11 có sẵn trên Python 3. 10+, nhưng hoàn toàn không được hiển thị trên các phiên bản Python trước đó. ]

Ghi chú

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
06 không có nghĩa là đối số hàm có giá trị mặc định. Nó đơn giản có nghĩa là
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 là một giá trị hợp lệ cho đối số. Đây là một sự nhầm lẫn phổ biến vì
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 là giá trị mặc định phổ biến cho các đối số

X. Cú pháp Y cho Unions

PEP 604 đã giới thiệu một cách khác để đánh vần các loại kết hợp. Trong Trăn 3. 10 trở lên, bạn có thể viết

def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
44 thành
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
20. Có thể sử dụng cú pháp này trong các phiên bản Python không được thời gian chạy hỗ trợ với một số hạn chế [xem phần ]

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
30

Vô hiệu hóa kiểm tra tùy chọn nghiêm ngặt

Mypy cũng có một tùy chọn để coi

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 là một giá trị hợp lệ cho mọi loại [trong trường hợp bạn biết Java, sẽ rất hữu ích khi coi nó tương tự như Java
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
22]. Trong chế độ này,
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 cũng hợp lệ đối với các loại nguyên thủy như
def wait[t: float] -> None:
    print['Waiting...']
    time.sleep[t]

if wait[2] > 1:   # Error: can't compare None and int
    ...
7 và
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
25 và các loại không bắt buộc

Chế độ được kích hoạt thông qua tùy chọn dòng lệnh. Trong các phiên bản mypy trước 0. 600 đây là chế độ mặc định. Bạn có thể bật tùy chọn này một cách rõ ràng để tương thích ngược với các phiên bản mypy trước đó, trong trường hợp bạn chưa muốn giới thiệu các loại tùy chọn cho cơ sở mã của mình

Nó sẽ khiến mypy âm thầm chấp nhận một số mã lỗi, chẳng hạn như ví dụ này – không nên dùng nếu bạn có thể tránh được

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
31

Tuy nhiên, làm cho mã "sạch tùy chọn" có thể mất một số công việc. Bạn cũng có thể sử dụng để di chuyển mã của mình sang kiểm tra tùy chọn nghiêm ngặt từng tệp một, vì tồn tại cờ trên mỗi mô-đun để kiểm soát chế độ tùy chọn nghiêm ngặt

Thông thường, việc ghi lại liệu một biến có thể là

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 hay không vẫn rất hữu ích. Ví dụ, chức năng này chấp nhận một đối số
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42, nhưng nó không rõ ràng từ chữ ký của nó

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
32

Bạn vẫn có thể sử dụng để ghi lại rằng

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 là loại đối số hợp lệ, ngay cả khi việc kiểm tra nghiêm ngặt
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 không được bật

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
33

Mypy coi điều này tương đương về mặt ngữ nghĩa với ví dụ trước nếu tính năng kiểm tra tùy chọn nghiêm ngặt bị vô hiệu hóa, vì

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 hoàn toàn hợp lệ đối với bất kỳ loại nào, nhưng nó hữu ích hơn nhiều đối với lập trình viên đang đọc mã. Điều này cũng giúp việc chuyển sang kiểm tra nghiêm ngặt
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42 trong tương lai trở nên dễ dàng hơn

Nhập bí danh

Trong một số trường hợp nhất định, tên nhập có thể dài và khó gõ

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
34

Khi những trường hợp như thế này phát sinh, bạn có thể xác định bí danh loại bằng cách gán loại cho một biến

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
35

Ghi chú

Một bí danh loại không tạo ra một loại mới. Nó chỉ là một ký hiệu viết tắt cho một loại khác – nó tương đương với loại mục tiêu ngoại trừ

Kể từ Mypy 0. 930, bạn cũng có thể sử dụng bí danh loại rõ ràng, được giới thiệu trong PEP 613

Có thể có sự nhầm lẫn về thời điểm chính xác khi một phép gán xác định bí danh kiểu ngầm định – ví dụ: khi bí danh chứa tham chiếu chuyển tiếp, kiểu không hợp lệ hoặc vi phạm một số hạn chế khác đối với khai báo bí danh kiểu. Bởi vì sự khác biệt giữa một biến không được chú thích và một bí danh kiểu là khai báo bí danh kiểu không rõ ràng hoặc không chính xác, mặc định để xác định một biến bình thường thay vì một bí danh kiểu

Bí danh loại rõ ràng là rõ ràng và cũng có thể cải thiện khả năng đọc bằng cách làm cho ý định rõ ràng

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
36

bộ dữ liệu được đặt tên

Mypy nhận ra các bộ dữ liệu được đặt tên và có thể nhập mã kiểm tra xác định hoặc sử dụng chúng. Trong ví dụ này, chúng tôi có thể phát hiện mã đang cố truy cập một thuộc tính bị thiếu

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
37

Nếu bạn sử dụng để xác định bộ dữ liệu được đặt tên của mình, tất cả các mục được giả định là có ____01 loại. Tức là, mypy không biết gì về các loại vật phẩm. Bạn cũng có thể sử dụng để xác định các loại mục

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
38

Trăn 3. 6 đã giới thiệu một cú pháp thay thế, dựa trên lớp cho các bộ dữ liệu được đặt tên với các loại

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
39

Ghi chú

Bạn có thể sử dụng “lớp giả”

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
38 thô trong chú thích loại nếu bất kỳ đối tượng
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
38 nào hợp lệ

Ví dụ, nó có thể hữu ích cho quá trình khử lưu huỳnh

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
50

Lưu ý rằng hành vi này mang tính thử nghiệm cao, không chuẩn và có thể không được hỗ trợ bởi các trình kiểm tra loại và IDE khác

Loại đối tượng lớp

[Tự do sau. ]

Đôi khi bạn muốn nói về các đối tượng lớp kế thừa từ một lớp nhất định. Điều này có thể được đánh vần là

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
41 [hoặc, trên Python 3. 8 trở xuống, ] trong đó
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
43 là một lớp. Nói cách khác, khi
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
43 là tên của một lớp, việc sử dụng
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
43 để chú thích một đối số sẽ tuyên bố rằng đối số đó là một thể hiện của
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
43 [hoặc một lớp con của
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
43], nhưng sử dụng
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
41 làm chú thích đối số sẽ tuyên bố rằng đối số đó là một

Ví dụ: giả sử các lớp sau

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
51

Lưu ý rằng

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
51 không kế thừa từ
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
52

Đây là một hàm tạo ra một thể hiện của một trong các lớp này nếu bạn truyền cho nó đúng đối tượng lớp

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
52

Làm thế nào chúng ta sẽ chú thích chức năng này?

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
53

Điều này có vẻ hợp lý, ngoại trừ trong ví dụ sau, mypy không thấy rằng biến

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
54 có kiểu
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
51

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
54

Tuy nhiên, sử dụng cú pháp

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
41 và một biến kiểu có giới hạn trên [xem ], chúng ta có thể làm tốt hơn

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
55

Bây giờ mypy sẽ suy ra loại kết quả chính xác khi chúng ta gọi

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
57 với một phân lớp cụ thể là
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
58

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
56

Ghi chú

Giá trị tương ứng với

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
41 phải là một đối tượng lớp thực tế là một kiểu con của
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
43. Hàm tạo của nó phải tương thích với hàm tạo của
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
43. Nếu
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
43 là một biến kiểu, cận trên của nó phải là một đối tượng lớp

Để biết thêm chi tiết về

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
63 và , xem

máy phát điện

Trình tạo cơ bản chỉ mang lại giá trị có thể được chú thích ngắn gọn là có kiểu trả về là hoặc. Ví dụ

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
57

Một nguyên tắc nhỏ là chú thích các hàm với kiểu trả về cụ thể nhất có thể. Tuy nhiên, bạn cũng nên cẩn thận để tránh rò rỉ chi tiết triển khai vào API công khai của chức năng. Để phù hợp với hai nguyên tắc này, hãy ưu tiên chú thích kiểu trả về cho hàm tạo, vì nó cho phép mypy biết rằng người dùng có thể gọi đối tượng được trả về bởi hàm. Tuy nhiên, hãy nhớ rằng đôi khi

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
70 có thể là lựa chọn tốt hơn, nếu bạn coi đó là một chi tiết triển khai mà
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
69 có thể được gọi trên đối tượng được hàm của bạn trả về

Mặt khác, nếu bạn muốn trình tạo của mình chấp nhận các giá trị thông qua phương thức hoặc trả về một giá trị, bạn nên sử dụng loại chung thay vì

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
74 hoặc
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
70. Ví dụ

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
58

Lưu ý rằng không giống như nhiều thuốc generic khác trong mô-đun đánh máy,

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
76 của hoạt động trái ngược, không đồng biến hoặc bất biến

Nếu bạn không có kế hoạch nhận hoặc trả lại các giá trị, thì hãy đặt

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
76 hoặc
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
79 thành
class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
42, nếu phù hợp. Ví dụ: chúng ta có thể chú thích ví dụ đầu tiên như sau

class A:
    def f[self] -> int:  # Type of self inferred [A]
        return 2

class B[A]:
    def f[self] -> int:
         return 3
    def g[self] -> int:
        return 4

def foo[a: A] -> None:
    print[a.f[]]  # 3
    a.g[]         # Error: "A" has no attribute "g"

foo[B[]]  # OK [B is a subclass of A]
59

Điều này hơi khác so với việc sử dụng

a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
81 hoặc
a: Any = None
s: str = ''
a = 2     # OK [assign "int" to "Any"]
s = a     # OK [assign "Any" to "str"]
82, vì các trình tạo có , và các phương thức mà các trình vòng lặp và trình lặp chung chung không có. Nếu bạn định gọi các phương thức này trên trình tạo được trả về, hãy sử dụng loại thay vì hoặc

Python có kiểm tra kiểu không?

Python sẽ luôn là ngôn ngữ được gõ động. Tuy nhiên, PEP 484 đã giới thiệu các gợi ý về loại, cho phép thực hiện kiểm tra loại tĩnh của mã Python . Không giống như cách các loại hoạt động trong hầu hết các ngôn ngữ được nhập tĩnh khác, bản thân các gợi ý nhập không khiến Python thực thi các loại.

Python gợi ý loại tùy chọn là gì?

Python có hỗ trợ cho "gợi ý loại" tùy chọn. Những "gợi ý kiểu" này là một cú pháp đặc biệt cho phép khai báo kiểu của một biến . Bằng cách khai báo các loại cho biến của bạn, trình chỉnh sửa và công cụ có thể hỗ trợ bạn tốt hơn.

Bạn có nên sử dụng gợi ý loại trong Python không?

Nếu bạn muốn viết mã python hiện đại và tăng chất lượng mã của mình, hãy nhập gợi ý . Tuy nhiên, có lẽ bạn nên tránh thêm gợi ý loại nếu bạn sử dụng phiên bản Python cũ, nếu bạn chưa quen với ngôn ngữ lập trình hoặc nếu hiệu suất là một vấn đề thực sự.

Chú thích kiểu trong Python là gì?

Chú thích loại là gì. ? . used to indicate the data types of variables and inputs/outputs of functions and methods.

Chủ Đề