TypedDict Python là gì?

Phần này giới thiệu một số loại bổ sung, bao gồm ,

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
9,
def Derived(_x):
    return _x
0 và các loại dành cho mã không đồng bộ. Nó cũng thảo luận về cách cung cấp cho các chức năng các loại chính xác hơn bằng cách sử dụng quá tải. Tất cả những thứ này chỉ hữu ích trong tình huống, vì vậy vui lòng bỏ qua phần này và quay lại khi bạn cần một số trong số chúng

Đây là một bản tóm tắt nhanh về những gì được đề cập ở đây

  • cho phép bạn nói với mypy rằng một chức năng không bao giờ trở lại bình thường

  • class Derived(Base):
        def __init__(self, _x: Base) -> None:
            ...
    
    9 cho phép bạn xác định một biến thể của một loại được mypy coi là một loại riêng biệt nhưng giống hệt với loại ban đầu khi chạy. Ví dụ: bạn có thể có
    def Derived(_x):
        return _x
    
    3 dưới dạng một biến thể của
    def Derived(_x):
        return _x
    
    4 chỉ là một
    def Derived(_x):
        return _x
    
    4 trong thời gian chạy

  • cho phép bạn xác định một chức năng có thể chấp nhận nhiều chữ ký riêng biệt. Điều này hữu ích nếu bạn cần mã hóa mối quan hệ giữa các đối số và kiểu trả về khó diễn đạt bình thường

  • def Derived(_x):
        return _x
    
    0 cho phép bạn cung cấp các loại chính xác cho từ điển đại diện cho các đối tượng có lược đồ cố định, chẳng hạn như
    def Derived(_x):
        return _x
    
    8

  • Các loại không đồng bộ cho phép bạn nhập các chương trình kiểm tra bằng cách sử dụng

    def Derived(_x):
        return _x
    
    9 và
    from typing import NewType
    
    UserId = NewType('UserId', int)
    
    def name_by_id(user_id: UserId) -> str:
        ...
    
    UserId('user')          # Fails type check
    
    name_by_id(42)          # Fails type check
    name_by_id(UserId(42))  # OK
    
    num: int = UserId(5) + 1
    
    0

Loại Không trả lại

Mypy cung cấp hỗ trợ cho các hàm không bao giờ quay lại. Ví dụ, một chức năng đưa ra một ngoại lệ vô điều kiện

from typing import NoReturn

def stop() -> NoReturn:
    raise Exception('no way')

Mypy sẽ đảm bảo rằng các chức năng được chú thích là trả về thực sự không bao giờ trả về, dù ngầm hay rõ ràng. Mypy cũng sẽ nhận ra rằng mã sau khi gọi các hàm như vậy là không thể truy cập được và sẽ hoạt động tương ứng

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block

Trong các phiên bản Python cũ hơn, bạn cần cài đặt

from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

UserId('user')          # Fails type check

name_by_id(42)          # Fails type check
name_by_id(UserId(42))  # OK

num: int = UserId(5) + 1
2 bằng cách sử dụng pip để sử dụng trong mã của mình. Dòng lệnh Python3

python3 -m pip install --upgrade typing-extensions

Loại mới

Có những tình huống mà bạn có thể muốn tránh các lỗi lập trình bằng cách tạo các lớp dẫn xuất đơn giản chỉ được sử dụng để phân biệt các giá trị nhất định với các thể hiện của lớp cơ sở. Ví dụ

class UserId(int):
    pass

def get_by_user_id(user_id: UserId):
    ...

Tuy nhiên, cách tiếp cận này giới thiệu một số chi phí thời gian chạy. Để tránh điều này, mô-đun đánh máy cung cấp một đối tượng trợ giúp

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
9 để tạo các kiểu duy nhất đơn giản với chi phí thời gian chạy gần như bằng không. Mypy sẽ coi câu lệnh
from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

UserId('user')          # Fails type check

name_by_id(42)          # Fails type check
name_by_id(UserId(42))  # OK

num: int = UserId(5) + 1
5 gần tương đương với định nghĩa sau

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...

Tuy nhiên, trong thời gian chạy,

from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

UserId('user')          # Fails type check

name_by_id(42)          # Fails type check
name_by_id(UserId(42))  # OK

num: int = UserId(5) + 1
6 sẽ trả về một giả có thể gọi được mà chỉ trả về đối số của nó

def Derived(_x):
    return _x

Mypy sẽ yêu cầu ép kiểu rõ ràng từ

def Derived(_x):
    return _x
4 khi dự kiến ​​là
def Derived(_x):
    return _x
3, trong khi ép kiểu ngầm định từ
def Derived(_x):
    return _x
3 khi dự kiến ​​là
def Derived(_x):
    return _x
4. ví dụ

from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

UserId('user')          # Fails type check

name_by_id(42)          # Fails type check
name_by_id(UserId(42))  # OK

num: int = UserId(5) + 1

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
9 chấp nhận chính xác hai đối số. Đối số đầu tiên phải là một chuỗi ký tự chứa tên của kiểu mới và phải bằng tên của biến mà kiểu mới được gán. Đối số thứ hai phải là một lớp có thể phân lớp đúng cách, tôi. e. , không phải là cấu trúc kiểu như , v.v.

Có thể gọi được trả về bởi

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
9 chỉ chấp nhận một đối số; . Ví dụ

from typing import NewType

class PacketId:
    def __init__(self, major: int, minor: int) -> None:
        self._major = major
        self._minor = minor

TcpPacketId = NewType('TcpPacketId', PacketId)

packet = PacketId(100, 100)
tcp_packet = TcpPacketId(packet)  # OK

tcp_packet = TcpPacketId(127, 0)  # Fails in type checker and at runtime

Bạn không thể sử dụng hoặc trên đối tượng được trả về bởi

from typing import NewType

class PacketId:
    def __init__(self, major: int, minor: int) -> None:
        self._major = major
        self._minor = minor

TcpPacketId = NewType('TcpPacketId', PacketId)

packet = PacketId(100, 100)
tcp_packet = TcpPacketId(packet)  # OK

tcp_packet = TcpPacketId(127, 0)  # Fails in type checker and at runtime
6, bạn cũng không thể phân lớp một đối tượng được trả về bởi
from typing import NewType

class PacketId:
    def __init__(self, major: int, minor: int) -> None:
        self._major = major
        self._minor = minor

TcpPacketId = NewType('TcpPacketId', PacketId)

packet = PacketId(100, 100)
tcp_packet = TcpPacketId(packet)  # OK

tcp_packet = TcpPacketId(127, 0)  # Fails in type checker and at runtime
6

Ghi chú

Không giống như bí danh loại,

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
9 sẽ tạo ra một loại hoàn toàn mới và duy nhất khi được sử dụng. Mục đích dự định của
class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
9 là giúp bạn phát hiện các trường hợp bạn vô tình trộn lẫn loại cơ sở cũ và loại dẫn xuất mới với nhau

Ví dụ: phần sau sẽ kiểm tra đánh máy thành công khi sử dụng bí danh loại

UserId = int

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # ints and UserId are synonymous

Nhưng một ví dụ tương tự sử dụng

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
9 sẽ không đánh máy

from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # int is not the same as UserId

nạp chồng hàm

Đôi khi các đối số và kiểu trong một hàm phụ thuộc vào nhau theo những cách không thể nắm bắt được bằng một. Ví dụ: giả sử chúng ta muốn viết một hàm có thể chấp nhận tọa độ x-y. Nếu chúng ta chỉ chuyển vào một tọa độ x-y duy nhất, chúng ta sẽ trả về một đối tượng

UserId = int

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # ints and UserId are synonymous
2. Tuy nhiên, nếu chúng ta chuyển vào hai tọa độ x-y, chúng ta sẽ trả về một đối tượng
UserId = int

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # ints and UserId are synonymous
3

Nỗ lực đầu tiên của chúng ta khi viết hàm này có thể trông như thế này

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
0

Trong khi chữ ký chức năng này hoạt động, nó quá lỏng lẻo. nó ngụ ý

UserId = int

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # ints and UserId are synonymous
4 có thể trả về một trong hai đối tượng bất kể số lượng đối số mà chúng ta truyền vào. Nó cũng không cấm người gọi chuyển sai số lượng int. ví dụ, mypy sẽ coi các cuộc gọi như
UserId = int

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # ints and UserId are synonymous
5 là hợp lệ

Chúng ta có thể làm tốt hơn bằng cách sử dụng which cho phép chúng ta cung cấp cho cùng một chức năng nhiều loại chú thích (chữ ký) để mô tả chính xác hơn hành vi của chức năng

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
1

Điều này cho phép mypy hiểu các cuộc gọi đến

UserId = int

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # ints and UserId are synonymous
4 chính xác hơn nhiều. Ví dụ, mypy sẽ hiểu rằng
UserId = int

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # ints and UserId are synonymous
7 sẽ luôn có kiểu trả về là
UserId = int

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # ints and UserId are synonymous
2 và sẽ báo lỗi cho các cuộc gọi như
UserId = int

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # ints and UserId are synonymous
9

Một ví dụ khác, giả sử chúng ta muốn viết một lớp vùng chứa tùy chỉnh triển khai phương thức (

from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # int is not the same as UserId
1 lập chỉ mục dấu ngoặc). Nếu phương thức này nhận được một số nguyên, chúng tôi trả về một mục duy nhất. Nếu nó nhận được một
from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # int is not the same as UserId
2, chúng tôi sẽ trả lại một trong số các mặt hàng

Chúng ta có thể mã hóa chính xác mối quan hệ này giữa đối số và kiểu trả về bằng cách sử dụng các quá tải như vậy

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
2

Ghi chú

Nếu bạn chỉ cần hạn chế một biến kiểu đối với một số kiểu hoặc kiểu con nhất định, bạn có thể sử dụng một

Các giá trị mặc định của các đối số của một hàm không ảnh hưởng đến chữ ký của nó – chỉ sự vắng mặt hoặc có mặt của một giá trị mặc định mới ảnh hưởng. Vì vậy, để giảm sự dư thừa, có thể thay thế các giá trị mặc định trong các định nghĩa quá tải bằng

from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # int is not the same as UserId
4 làm trình giữ chỗ

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
3

hành vi thời gian chạy

Một chức năng quá tải phải bao gồm hai hoặc nhiều biến thể quá tải theo sau là một triển khai. Các biến thể và triển khai phải liền kề trong mã. nghĩ về chúng như một đơn vị không thể chia cắt

Tất cả các cơ thể biến thể phải trống; . Điều này là do trong thời gian chạy, các biến thể hoàn toàn bị bỏ qua. chúng bị ghi đè bởi chức năng thực hiện cuối cùng

Điều này có nghĩa là một hàm quá tải vẫn là một hàm Python bình thường. Không có xử lý công văn tự động và bạn phải xử lý thủ công các loại khác nhau trong quá trình triển khai (e. g. bằng cách sử dụng câu lệnh và kiểm tra

from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # int is not the same as UserId
5)

Nếu bạn đang thêm một tình trạng quá tải trong một tệp sơ khai, chức năng thực hiện sẽ được bỏ qua. sơ khai không chứa logic thời gian chạy

Ghi chú

Mặc dù chúng ta có thể để trống nội dung biến thể bằng cách sử dụng từ khóa

from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # int is not the same as UserId
7, nhưng quy ước phổ biến hơn là sử dụng dấu chấm lửng (
from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # int is not the same as UserId
4) thay vào đó

Loại kiểm tra các cuộc gọi đến quá tải

Khi bạn gọi một hàm bị quá tải, mypy sẽ suy ra kiểu trả về chính xác bằng cách chọn biến thể phù hợp nhất, sau khi xem xét cả kiểu đối số và đối số. Tuy nhiên, một cuộc gọi không bao giờ được kiểm tra loại đối với việc thực hiện. Đây là lý do tại sao mypy sẽ báo cáo các cuộc gọi như

from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # int is not the same as UserId
9 là không hợp lệ mặc dù nó khớp với chữ ký triển khai

Nếu có nhiều biến thể phù hợp tốt như nhau, mypy sẽ chọn biến thể được xác định trước. Ví dụ, hãy xem xét chương trình sau

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
4

Cuộc gọi

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
00 phù hợp với cả hai biến thể. một danh sách trống có thể là một
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
01 hoặc một
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
02. Trong trường hợp này, mypy sẽ phá vỡ thế ràng buộc bằng cách chọn biến thể phù hợp đầu tiên.
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
03 sẽ có kiểu suy ra là
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
04. Người triển khai chịu trách nhiệm đảm bảo rằng
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
05 phá vỡ các ràng buộc theo cùng một cách trong thời gian chạy

Tuy nhiên, có hai trường hợp ngoại lệ đối với quy tắc “chọn trận đấu đầu tiên”. Đầu tiên, nếu nhiều biến thể khớp do một đối số thuộc loại

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
06, thì mypy sẽ làm cho loại được suy luận cũng là
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
06

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
5

Thứ hai, nếu nhiều biến thể khớp với nhau do một hoặc nhiều đối số là kết hợp, mypy sẽ biến loại được suy luận thành kết hợp của biến thể phù hợp trả về

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
6

Ghi chú

Do quy tắc "chọn kết quả đầu tiên", việc thay đổi thứ tự các biến thể quá tải của bạn có thể thay đổi cách loại mypy kiểm tra chương trình của bạn

Để giảm thiểu các sự cố tiềm ẩn, chúng tôi khuyên bạn nên

  1. Đảm bảo rằng các biến thể quá tải của bạn được liệt kê theo cùng thứ tự khi kiểm tra thời gian chạy (e. g. kiểm tra) trong quá trình thực hiện của bạn

  2. Đặt hàng các biến thể của bạn và kiểm tra thời gian chạy từ cụ thể nhất đến cụ thể nhất. (Xem phần sau để biết ví dụ)

Nhập kiểm tra các biến thể

Mypy sẽ thực hiện một số kiểm tra đối với định nghĩa biến thể quá tải của bạn để đảm bảo chúng hoạt động như mong đợi. Đầu tiên, mypy sẽ kiểm tra và đảm bảo rằng không có biến thể quá tải nào che khuất biến thể tiếp theo. Ví dụ, hãy xem xét hàm sau cộng hai đối tượng

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
09 lại với nhau và chứa một trường hợp đặc biệt để xử lý việc nhận hai loại
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
10

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
7

Mặc dù đoạn mã này an toàn về mặt kỹ thuật, nhưng nó chứa một mẫu chống. biến thể thứ hai sẽ không bao giờ được chọn. Nếu chúng tôi thử gọi

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
11, mypy sẽ luôn chọn biến thể đầu tiên và đánh giá lệnh gọi hàm thuộc loại
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
09, không phải
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
10. Điều này là do
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
10 là một kiểu con của
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
09, có nghĩa là quy tắc "chọn kết quả đầu tiên" sẽ luôn dừng sau khi xem xét quá tải đầu tiên

Bởi vì có một biến thể quá tải không bao giờ có thể khớp được gần như chắc chắn là một lỗi, mypy sẽ báo lỗi. Để sửa lỗi, chúng ta có thể 1) xóa quá tải thứ hai hoặc 2) hoán đổi thứ tự của các lần quá tải

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
8

Mypy cũng sẽ gõ kiểm tra các biến thể khác nhau và gắn cờ bất kỳ tình trạng quá tải nào vốn có các biến thể chồng chéo không an toàn. Ví dụ, xem xét định nghĩa quá tải không an toàn sau đây

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
9

Nhìn bề ngoài, định nghĩa chức năng này có vẻ ổn. Tuy nhiên, nó sẽ dẫn đến sự khác biệt giữa loại được suy luận và loại thời gian chạy thực tế khi chúng tôi thử sử dụng nó như vậy

python3 -m pip install --upgrade typing-extensions
0

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
16 thuộc loại , mypy sẽ quyết định rằng
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
18 phải trả lại thứ gì đó thuộc loại
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
19 và kết luận ở trên sẽ loại kiểm tra. Nhưng trên thực tế,
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
18 sẽ trả về một int, khiến mã bị lỗi khi chạy

Để ngăn chặn các loại sự cố này, mypy sẽ phát hiện và ngăn chặn tình trạng quá tải chồng chéo vốn không an toàn trên cơ sở cố gắng hết sức. Hai biến thể được coi là chồng chéo không an toàn khi cả hai điều sau đây đều đúng

  1. Tất cả các đối số của biến thể đầu tiên đều tương thích với biến thể thứ hai

  2. Kiểu trả về của biến thể đầu tiên không tương thích với (e. g. không phải là một kiểu con của) thứ hai

Vì vậy, trong ví dụ này, đối số

def Derived(_x):
    return _x
4 trong biến thể đầu tiên là một kiểu con của đối số
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
17 trong biến thể thứ hai, nhưng kiểu trả về
def Derived(_x):
    return _x
4 không phải là kiểu con của
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
19. Cả hai điều kiện đều đúng, vì vậy mypy sẽ gắn cờ chính xác
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
18 là không an toàn

Tuy nhiên, mypy sẽ không phát hiện tất cả các trường hợp sử dụng quá tải không an toàn. Ví dụ: giả sử chúng tôi sửa đổi đoạn mã trên để nó gọi

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
05 thay vì
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
18

python3 -m pip install --upgrade typing-extensions
1

Chúng tôi gặp sự cố tương tự ở đây. Loại chương trình này kiểm tra nếu chúng ta chỉ nhìn vào các chú thích về tình trạng quá tải. Nhưng vì

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
28 được thiết kế để thiên về trả về số float khi nó nhận được một danh sách trống, nên chương trình này thực sự sẽ gặp sự cố trong thời gian chạy

Lý do mypy không gắn cờ các định nghĩa như

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
05 là có khả năng không an toàn là vì nếu làm như vậy, sẽ cực kỳ khó để viết quá tải an toàn. Ví dụ: giả sử chúng tôi xác định tình trạng quá tải với hai biến thể chấp nhận các loại lần lượt là
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
30 và
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
31. Ngay cả khi hai loại đó hoàn toàn không liên quan, người dùng vẫn có khả năng gây ra lỗi thời gian chạy tương tự như lỗi ở trên bằng cách chuyển vào một giá trị của loại thứ ba nào đó
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
32 kế thừa từ cả hai loại
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
30 và
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
31

Rất may, những loại tình huống này là tương đối hiếm. Tuy nhiên, điều này có nghĩa là bạn nên thận trọng khi thiết kế hoặc sử dụng một hàm quá tải có khả năng nhận các giá trị là một thể hiện của hai loại dường như không liên quan

Loại kiểm tra việc thực hiện

Phần thân của một triển khai được kiểm tra kiểu đối với các gợi ý loại được cung cấp khi triển khai. Ví dụ: trong ví dụ

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
35 ở trên, mã trong phần thân được kiểm tra với danh sách đối số
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
36 và kiểu trả về là
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
37. Nếu không có chú thích nào khi triển khai, thì phần thân không được kiểm tra loại. Nếu bạn vẫn muốn buộc mypy kiểm tra phần thân, hãy sử dụng cờ ()

Các biến thể cũng phải tương thích với các gợi ý về loại triển khai. Trong ví dụ về

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
35, mypy sẽ kiểm tra xem loại tham số
def Derived(_x):
    return _x
4 và loại trả về
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
41 có tương thích với
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
42 và
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
43 cho biến thể đầu tiên không. Đối với biến thể thứ hai, nó xác minh loại tham số
from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # int is not the same as UserId
2 và loại trả về
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
45 tương thích với
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
42 và
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
43

Ghi chú

Ngữ nghĩa quá tải được ghi lại ở trên là mới kể từ mypy 0. 620

Trước đây, mypy đã từng thực hiện xóa kiểu trên tất cả các biến thể quá tải. Ví dụ: ví dụ

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
05 từ phần trước từng là bất hợp pháp vì cả
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
02 và
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
01 đều bị xóa thành chỉ còn ____11_______51. Hạn chế này đã được gỡ bỏ trong mypy 0. 620

Mypy trước đây cũng được sử dụng để chọn biến thể phù hợp nhất bằng thuật toán khác. Nếu thuật toán này không tìm thấy kết quả phù hợp, nó sẽ mặc định trả về

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
06. Thuật toán mới sử dụng quy tắc “chọn kết quả đầu tiên” và sẽ chỉ quay lại trả về
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
06 nếu các đối số đầu vào cũng chứa
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
06

quá tải có điều kiện

Đôi khi rất hữu ích khi xác định quá tải theo điều kiện. Các trường hợp sử dụng phổ biến bao gồm các loại không khả dụng trong thời gian chạy hoặc chỉ tồn tại trong một phiên bản Python nhất định. Tất cả các quy tắc quá tải hiện có vẫn được áp dụng. Ví dụ, phải có ít nhất hai lần quá tải

Ghi chú

Mypy chỉ có thể suy ra một số điều kiện hạn chế. Những cái được hỗ trợ hiện bao gồm ,

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
56, , , và các giá trị

python3 -m pip install --upgrade typing-extensions
2

python3 -m pip install --upgrade typing-extensions
3

Ghi chú

Trong ví dụ trước, mypy được thực thi với. Do đó, điều kiện

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
60 sẽ khớp và quá tải cho
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
31 sẽ được thêm vào. Quá tải cho
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
30 và
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
32 được bỏ qua. Quá tải cho
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
64 không được xác định có điều kiện và do đó cũng được thêm vào

Khi mypy không thể suy ra một điều kiện là luôn luôn

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
65 hoặc luôn luôn là
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
66, một lỗi sẽ được phát ra

python3 -m pip install --upgrade typing-extensions
4

Sử dụng nâng cao các loại tự

Thông thường, mypy không yêu cầu chú thích cho các đối số đầu tiên của các phương thức lớp và thể hiện. Tuy nhiên, chúng có thể cần thiết để gõ tĩnh chính xác hơn cho các mẫu lập trình nhất định

Các phương thức bị hạn chế trong các lớp chung

Trong các lớp chung, một số phương thức có thể chỉ được phép gọi đối với các giá trị nhất định của đối số kiểu

python3 -m pip install --upgrade typing-extensions
5

Mẫu này cũng cho phép đối sánh trên các loại lồng nhau trong các tình huống mà đối số loại chính nó là chung chung

python3 -m pip install --upgrade typing-extensions
6

Cuối cùng, người ta có thể sử dụng quá tải trên tự loại để thể hiện các loại chính xác của một số phương thức phức tạp

python3 -m pip install --upgrade typing-extensions
7

Cụ thể, một phương thức được nạp chồng trên kiểu tự có thể hữu ích để chú thích các hàm tạo của lớp chung trong đó các đối số kiểu phụ thuộc vào các tham số của hàm tạo theo một cách không tầm thường, xem e. g.

lớp trộn

Sử dụng giao thức lớp máy chủ làm phương thức tự nhập trong các phương thức mixin cho phép nhiều khả năng sử dụng lại mã hơn để nhập tĩnh các lớp mixin. Ví dụ: người ta có thể định nghĩa một giao thức xác định chức năng chung cho các lớp máy chủ thay vì thêm các phương thức trừu tượng bắt buộc vào mọi mixin

python3 -m pip install --upgrade typing-extensions
8

Lưu ý rằng kiểu tự rõ ràng được yêu cầu là một giao thức bất cứ khi nào nó không phải là siêu kiểu của lớp hiện tại. Trong trường hợp này, mypy sẽ chỉ kiểm tra tính hợp lệ của kiểu tự nhập tại trang cuộc gọi

Gõ chính xác các hàm tạo thay thế

Một số lớp có thể định nghĩa các hàm tạo thay thế. Nếu các lớp này là chung chung, tự nhập cho phép cung cấp cho chúng chữ ký chính xác

python3 -m pip install --upgrade typing-extensions
9

Nhập không đồng bộ/đang chờ

Mypy hỗ trợ khả năng nhập coroutine sử dụng cú pháp

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
69 được giới thiệu trong Python 3. 5. Để biết thêm thông tin về coroutines và cú pháp mới này, hãy xem PEP 492

Các hàm được xác định bằng cách sử dụng

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
70 được nhập giống như các hàm thông thường. Chú thích loại trả về phải giống với loại giá trị mà bạn muốn nhận lại khi
from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

UserId('user')          # Fails type check

name_by_id(42)          # Fails type check
name_by_id(UserId(42))  # OK

num: int = UserId(5) + 1
0-ing coroutine

class UserId(int):
    pass

def get_by_user_id(user_id: UserId):
    ...
0

Kết quả của việc gọi một hàm

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
70 mà không chờ đợi sẽ là một giá trị của loại , là một loại con của

class UserId(int):
    pass

def get_by_user_id(user_id: UserId):
    ...
1

Ghi chú

hiển thị loại tĩnh được suy ra của một biểu thức

Bạn cũng có thể chọn tạo một phân lớp thay thế

class UserId(int):
    pass

def get_by_user_id(user_id: UserId):
    ...
2

Để tạo một coroutine có thể lặp lại, phân lớp

class UserId(int):
    pass

def get_by_user_id(user_id: UserId):
    ...
3

Nếu bạn sử dụng coroutines trong mã kế thừa ban đầu được viết cho Python 3. 4, không hỗ trợ cú pháp

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
70, thay vào đó, bạn sẽ sử dụng trình trang trí
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
78 để chuyển trình tạo thành quy trình đăng quang và sử dụng loại trình tạo làm kiểu trả về

class UserId(int):
    pass

def get_by_user_id(user_id: UserId):
    ...
4

đã gõDict

Các chương trình Python thường sử dụng từ điển với các phím chuỗi để biểu diễn các đối tượng. Đây là một ví dụ điển hình

class UserId(int):
    pass

def get_by_user_id(user_id: UserId):
    ...
5

Dự kiến ​​chỉ có một bộ khóa chuỗi cố định (

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
79 và
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
80 ở trên) và mỗi khóa có một loại giá trị độc lập (
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
19 cho
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
79 và
def Derived(_x):
    return _x
4 cho
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
80 ở trên). Trước đây chúng ta đã thấy loại
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
85, cho phép bạn khai báo các loại từ điển thống nhất, trong đó mọi giá trị đều có cùng loại và các khóa tùy ý được hỗ trợ. Điều này rõ ràng không phù hợp với
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
86 ở trên. Thay vào đó, bạn có thể sử dụng
def Derived(_x):
    return _x
0 để cung cấp loại chính xác cho các đối tượng như
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
86, trong đó loại của từng giá trị từ điển phụ thuộc vào khóa

class UserId(int):
    pass

def get_by_user_id(user_id: UserId):
    ...
6

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
89 là loại
def Derived(_x):
    return _x
0 có hai mục.
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
79 (với loại
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
19) và
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
80 (với loại
def Derived(_x):
    return _x
4). Lưu ý rằng chúng tôi đã sử dụng chú thích loại rõ ràng cho biến
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
86. Chú thích loại này rất quan trọng – nếu không có nó, mypy sẽ cố gắng suy ra một loại thống nhất, thông thường cho
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
86, đây không phải là điều chúng tôi muốn ở đây

Ghi chú

Nếu bạn chuyển một đối tượng

def Derived(_x):
    return _x
0 làm đối số cho một hàm, thì thường không cần chú thích loại vì mypy có thể suy ra loại mong muốn dựa trên loại đối số đã khai báo. Ngoài ra, nếu một mục tiêu gán đã được xác định trước đó và nó có loại
def Derived(_x):
    return _x
0, thì mypy sẽ coi giá trị được gán là
def Derived(_x):
    return _x
0, chứ không phải

Bây giờ mypy sẽ nhận ra những thứ này là hợp lệ

class UserId(int):
    pass

def get_by_user_id(user_id: UserId):
    ...
7

Mypy sẽ phát hiện khóa không hợp lệ là lỗi

class UserId(int):
    pass

def get_by_user_id(user_id: UserId):
    ...
8

Mypy cũng sẽ từ chối biểu thức được tính toán trong thời gian chạy dưới dạng khóa vì nó không thể xác minh rằng đó là khóa hợp lệ. Bạn chỉ có thể sử dụng chuỗi ký tự như khóa

def Derived(_x):
    return _x
0

Đối tượng kiểu

def Derived(_x):
    return _x
0 cũng có thể hoạt động như một hàm tạo. Nó trả về một đối tượng bình thường trong thời gian chạy – một
def Derived(_x):
    return _x
0 không xác định loại thời gian chạy mới

class UserId(int):
    pass

def get_by_user_id(user_id: UserId):
    ...
9

Điều này tương đương với việc chỉ xây dựng một từ điển trực tiếp bằng cách sử dụng

python3 -m pip install --upgrade typing-extensions
06 hoặc
python3 -m pip install --upgrade typing-extensions
07. Biểu mẫu hàm tạo đôi khi thuận tiện vì nó có thể được sử dụng mà không cần chú thích kiểu và nó cũng làm rõ kiểu của đối tượng

Giống như tất cả các loại, các

def Derived(_x):
    return _x
0 có thể được sử dụng làm thành phần để xây dựng các loại phức tạp tùy ý. Ví dụ: bạn có thể xác định các
def Derived(_x):
    return _x
0 lồng nhau và vùng chứa với các mục
def Derived(_x):
    return _x
0. Không giống như hầu hết các loại khác, mypy sử dụng kiểm tra tính tương thích cấu trúc (hoặc phân loại cấu trúc) với các
def Derived(_x):
    return _x
0. Một đối tượng
def Derived(_x):
    return _x
0 với các mục bổ sung tương thích với (một loại phụ của) một
def Derived(_x):
    return _x
0 hẹp hơn, giả sử các loại mục tương thích (tổng số cũng ảnh hưởng đến việc phân loại phụ, như được thảo luận bên dưới)

Một đối tượng

def Derived(_x):
    return _x
0 không phải là một kiểu con của kiểu
python3 -m pip install --upgrade typing-extensions
15 thông thường (và ngược lại), vì nó cho phép thêm và bớt các khóa tùy ý, không giống như đối tượng
def Derived(_x):
    return _x
0. Tuy nhiên, bất kỳ đối tượng
def Derived(_x):
    return _x
0 nào cũng là một kiểu con của (nghĩa là tương thích với)
python3 -m pip install --upgrade typing-extensions
19, vì chỉ cung cấp quyền truy cập chỉ đọc vào các mục từ điển

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
0

Ghi chú

Trừ khi bạn đang sử dụng Python 3. 8 hoặc mới hơn (nơi có sẵn

def Derived(_x):
    return _x
0 trong mô-đun thư viện tiêu chuẩn), bạn cần cài đặt
from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

UserId('user')          # Fails type check

name_by_id(42)          # Fails type check
name_by_id(UserId(42))  # OK

num: int = UserId(5) + 1
2 bằng cách sử dụng pip để sử dụng
def Derived(_x):
    return _x
0

python3 -m pip install --upgrade typing-extensions

toàn bộ

Theo mặc định, mypy đảm bảo rằng một đối tượng

def Derived(_x):
    return _x
0 có tất cả các khóa được chỉ định. Điều này sẽ được gắn cờ là một lỗi

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
2

Đôi khi bạn muốn cho phép bỏ qua các phím khi tạo một đối tượng

def Derived(_x):
    return _x
0. Bạn có thể cung cấp đối số
python3 -m pip install --upgrade typing-extensions
27 cho
python3 -m pip install --upgrade typing-extensions
28 để đạt được điều này

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
3

Bạn có thể cần sử dụng để truy cập các mục của một phần (không phải toàn bộ)

def Derived(_x):
    return _x
0, vì việc lập chỉ mục bằng cách sử dụng
from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # int is not the same as UserId
1 có thể không thành công trong thời gian chạy. Tuy nhiên, mypy vẫn cho phép sử dụng
from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # int is not the same as UserId
1 với một phần
def Derived(_x):
    return _x
0 – bạn chỉ cần cẩn thận với nó, vì nó có thể dẫn đến. Yêu cầu mọi nơi sẽ quá cồng kềnh. (Lưu ý rằng bạn cũng có thể sử dụng miễn phí với tổng số
def Derived(_x):
    return _x
0. )

Các khóa không bắt buộc được hiển thị với một

python3 -m pip install --upgrade typing-extensions
38 trong thông báo lỗi

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
4

Tính tổng thể cũng ảnh hưởng đến khả năng tương thích cấu trúc. Bạn không thể sử dụng một phần

def Derived(_x):
    return _x
0 khi dự kiến ​​sẽ có một tổng số. Ngoài ra, tổng số
def Derived(_x):
    return _x
0 không hợp lệ khi một phần được mong đợi

hoạt động được hỗ trợ

def Derived(_x):
    return _x
0 đối tượng hỗ trợ một tập hợp con các hoạt động và phương thức từ điển. Bạn phải sử dụng chuỗi ký tự làm khóa khi gọi hầu hết các phương thức, nếu không thì mypy sẽ không thể kiểm tra xem khóa có hợp lệ không. Danh sách các hoạt động được hỗ trợ

  • Bất cứ điều gì bao gồm trong

    • python3 -m pip install --upgrade typing-extensions
      
      43

    • python3 -m pip install --upgrade typing-extensions
      
      44

    • python3 -m pip install --upgrade typing-extensions
      
      45

    • python3 -m pip install --upgrade typing-extensions
      
      46 (lặp lại)

  • (chỉ một phần của

    def Derived(_x):
        return _x
    
    0s)

  • python3 -m pip install --upgrade typing-extensions
    
    56 (chỉ một phần của
    def Derived(_x):
        return _x
    
    0s)

Ghi chú

và không được hỗ trợ vì chúng không an toàn – chúng có thể xóa các mục

def Derived(_x):
    return _x
0 bắt buộc không hiển thị với mypy do phân loại cấu trúc

Cú pháp dựa trên lớp

Một cú pháp thay thế, dựa trên lớp để xác định một

def Derived(_x):
    return _x
0 được hỗ trợ trong Python 3. 6 trở lên

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
5

Định nghĩa trên tương đương với định nghĩa gốc của

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
89. Nó không thực sự định nghĩa một lớp thực. Cú pháp này cũng hỗ trợ một hình thức thừa kế - các lớp con có thể xác định các mục bổ sung. Tuy nhiên, đây chủ yếu là một phím tắt công chứng. Vì mypy sử dụng khả năng tương thích cấu trúc với các
def Derived(_x):
    return _x
0, nên không cần kế thừa để tương thích. Đây là một ví dụ về thừa kế

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
6

Hiện tại,

python3 -m pip install --upgrade typing-extensions
64 có các khóa
python3 -m pip install --upgrade typing-extensions
65,
python3 -m pip install --upgrade typing-extensions
66 và
python3 -m pip install --upgrade typing-extensions
67

Trộn các mục bắt buộc và không bắt buộc

Ngoài việc cho phép sử dụng lại trên các loại

def Derived(_x):
    return _x
0, tính kế thừa còn cho phép bạn kết hợp các mục bắt buộc và không bắt buộc (sử dụng
python3 -m pip install --upgrade typing-extensions
27) trong một
def Derived(_x):
    return _x
0. Thí dụ

class Derived(Base):
    def __init__(self, _x: Base) -> None:
        ...
7

Bây giờ

def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
89 có các khóa bắt buộc là
python3 -m pip install --upgrade typing-extensions
65 và
python3 -m pip install --upgrade typing-extensions
66, trong khi có thể bỏ qua
python3 -m pip install --upgrade typing-extensions
67 khi xây dựng một đối tượng. Một
def Derived(_x):
    return _x
0 với sự kết hợp của các khóa bắt buộc và không bắt buộc, chẳng hạn như
def f(x: int) -> int:
    if x == 0:
        return x
    stop()
    return 'whatever works'  # No error in an unreachable block
89 ở trên, sẽ chỉ tương thích với một
def Derived(_x):
    return _x
0 khác nếu tất cả các khóa bắt buộc trong
def Derived(_x):
    return _x
0 kia là các khóa bắt buộc trong
def Derived(_x):
    return _x
0 đầu tiên và tất cả các khóa không bắt buộc của
def Derived(_x):
    return _x
0 khác

Công đoàn của TypedDicts

Vì TypedDicts thực sự chỉ là các ký tự thông thường trong thời gian chạy, nên không thể sử dụng kiểm tra

from typing import NewType

UserId = NewType('UserId', int)

def name_by_id(user_id: UserId) -> str:
    ...

name_by_id(3)  # int is not the same as UserId
6 để phân biệt giữa các biến thể khác nhau của Union of TypedDict giống như cách bạn có thể làm với các đối tượng thông thường

Thay vào đó, bạn có thể sử dụng. Phần được tham chiếu của tài liệu có mô tả đầy đủ kèm theo ví dụ, nhưng tóm lại, bạn sẽ cần cung cấp cho mỗi TypedDict một khóa giống nhau trong đó mỗi giá trị có một giá trị duy nhất. Sau đó, kiểm tra khóa đó để phân biệt giữa TypedDicts của bạn

Sự khác biệt giữa dict và TypedDict là gì?

Chính tả [phím. value] cho phép bạn khai báo các loại từ điển thống nhất, trong đó mọi giá trị đều có cùng loại và các khóa tùy ý được hỗ trợ. Nhưng TypedDict cho phép chúng tôi mô tả một từ điển/bản đồ có cấu trúc trong đó loại của từng giá trị từ điển phụ thuộc vào khóa như các bài hát như trong ví dụ dưới đây

Mục đích của gợi ý kiểu trong Python là gì?

Gợi ý loại được thực hiện bằng chú thích Python (được giới thiệu từ PEP 3107). Chúng được sử dụng để thêm kiểu vào biến, tham số, đối số hàm cũng như giá trị trả về, thuộc tính lớp và phương thức của chúng . Thêm gợi ý loại không có hiệu ứng thời gian chạy. đây chỉ là những gợi ý và không được thực thi trên chính chúng.

Sự khác biệt giữa NamedTuple và TypedDict trong Python là gì?

NamedTuple là một siêu lớp đánh máy cho các đối tượng có cấu trúc từ các bộ sưu tập. nhà máy được đặt tên;