Loại đối tượng nào có thể được sử dụng trong từ điển trong Python?

PEP 484 xác định loại

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
1 cho các từ điển thống nhất, trong đó mỗi giá trị có cùng loại và các giá trị khóa tùy ý được hỗ trợ. Nó không hỗ trợ đúng mẫu phổ biến trong đó loại giá trị từ điển phụ thuộc vào giá trị chuỗi của khóa. PEP này đề xuất một hàm tạo kiểu
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
2 để hỗ trợ trường hợp sử dụng trong đó một đối tượng từ điển có một bộ khóa chuỗi cụ thể, mỗi khóa có một giá trị của một loại cụ thể

Đây là một ví dụ trong đó PEP 484 không cho phép chúng tôi chú thích thỏa đáng

movie = {'name': 'Blade Runner',
         'year': 1982}

PEP này đề xuất bổ sung một hàm tạo kiểu mới, được gọi là

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
3, để cho phép biểu diễn chính xác kiểu của
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
4

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int

Bây giờ, trình kiểm tra loại sẽ chấp nhận mã này

movie: Movie = {'name': 'Blade Runner',
                'year': 1982}

Động lực

Biểu diễn một đối tượng hoặc dữ liệu có cấu trúc bằng cách sử dụng từ điển [có khả năng được lồng vào nhau] bằng các khóa chuỗi [thay vì lớp do người dùng định nghĩa] là một mẫu phổ biến trong các chương trình Python. Đại diện cho các đối tượng JSON có lẽ là trường hợp sử dụng chính tắc và điều này đủ phổ biến để Python cung cấp thư viện JSON. PEP này đề xuất một cách để cho phép loại mã đó được kiểm tra hiệu quả hơn

Tổng quát hơn, việc biểu diễn các đối tượng dữ liệu thuần túy chỉ sử dụng các kiểu nguyên thủy của Python như từ điển, chuỗi và danh sách đã có sức hấp dẫn nhất định. Chúng dễ tuần tự hóa và giải tuần tự hóa ngay cả khi không sử dụng JSON. Chúng hỗ trợ một cách tầm thường các hoạt động hữu ích khác nhau mà không cần nỗ lực thêm, bao gồm in ấn đẹp [thông qua mô-đun

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
5 và
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
6], lặp lại và so sánh đẳng thức

PEP 484 không hỗ trợ đúng cách các trường hợp sử dụng được đề cập ở trên. Hãy xem xét một đối tượng từ điển có chính xác hai khóa chuỗi hợp lệ,

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
7 với loại giá trị
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
8 và
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
9 với loại giá trị
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
20. Loại PEP 484
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
21 sẽ phù hợp, nhưng nó quá nhẹ vì có thể sử dụng các khóa chuỗi tùy ý và các giá trị tùy ý là hợp lệ. Tương tự,
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
22 là quá chung chung, vì giá trị của khóa
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
7 có thể là một
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
20 và các khóa chuỗi tùy ý được cho phép. Ngoài ra, loại biểu thức đăng ký, chẳng hạn như
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
25 [giả sử
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
26 là từ điển thuộc loại này] sẽ là
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
27, quá rộng

Lớp dữ liệu là một giải pháp thay thế gần đây hơn để giải quyết trường hợp sử dụng này, nhưng vẫn còn rất nhiều mã hiện có được viết trước khi lớp dữ liệu có sẵn, đặc biệt là trong các cơ sở mã lớn hiện có, nơi gợi ý và kiểm tra kiểu đã được chứng minh là hữu ích. Không giống như các đối tượng từ điển, các lớp dữ liệu không hỗ trợ trực tiếp quá trình tuần tự hóa JSON, mặc dù có một gói của bên thứ ba thực hiện nó [1]

Sự chỉ rõ

Loại TypedDict đại diện cho các đối tượng từ điển với một bộ khóa chuỗi cụ thể và với các loại giá trị cụ thể cho từng khóa hợp lệ. Mỗi khóa chuỗi có thể là bắt buộc [phải có] hoặc không bắt buộc [không cần tồn tại]

PEP này đề xuất hai cách xác định các loại TypedDict. Cái đầu tiên sử dụng cú pháp dựa trên lớp. Thứ hai là một cú pháp dựa trên phép gán thay thế được cung cấp để tương thích ngược, để cho phép tính năng này được nhập vào các phiên bản Python cũ hơn. Lý do tương tự như lý do tại sao PEP 484 hỗ trợ cú pháp chú thích dựa trên nhận xét cho Python 2. 7. gợi ý kiểu đặc biệt hữu ích cho các cơ sở mã lớn hiện có và chúng thường cần chạy trên các phiên bản Python cũ hơn. Hai tùy chọn cú pháp song song với các biến thể cú pháp được hỗ trợ bởi

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
28. Các tính năng được đề xuất khác bao gồm tính kế thừa và tính toàn bộ của TypedDict [chỉ định có bắt buộc phải có khóa hay không]

PEP này cũng cung cấp một bản phác thảo về cách trình kiểm tra kiểu sẽ hỗ trợ các hoạt động kiểm tra kiểu liên quan đến các đối tượng TypedDict. Tương tự như PEP 484, mục đích thảo luận này hơi mơ hồ, để cho phép thử nghiệm nhiều phương pháp kiểm tra kiểu khác nhau. Cụ thể, khả năng tương thích kiểu phải dựa trên khả năng tương thích cấu trúc. một loại TypedDict cụ thể hơn có thể tương thích với một loại TypedDict nhỏ hơn [tổng quát hơn]

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

Loại TypedDict có thể được định nghĩa bằng cách sử dụng cú pháp định nghĩa lớp với

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
2 là lớp cơ sở duy nhất

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int

movie: Movie = {'name': 'Blade Runner',
                'year': 1982}
0 là loại TypedDict có hai mục.
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
7 [với loại
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
8] và
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
9 [với loại
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
20]

Trình kiểm tra loại phải xác thực rằng phần thân của định nghĩa TypedDict dựa trên lớp tuân theo các quy tắc sau

  • Nội dung lớp chỉ nên chứa các dòng có định nghĩa mục có dạng
    movie: Movie = {'name': 'Blade Runner',
                    'year': 1982}
    
    5, tùy ý bắt đầu bằng một chuỗi tài liệu. Cú pháp cho định nghĩa mục giống với chú thích thuộc tính, nhưng không được có bộ khởi tạo và tên khóa thực sự đề cập đến giá trị chuỗi của khóa thay vì tên thuộc tính
  • Không thể sử dụng nhận xét loại với cú pháp dựa trên lớp, để thống nhất với cú pháp
    movie: Movie = {'name': 'Blade Runner',
                    'year': 1982}
    
    6 dựa trên lớp. [Lưu ý rằng sẽ không đủ để hỗ trợ nhận xét loại để tương thích ngược với Python 2. 7, vì định nghĩa lớp có thể có đối số từ khóa
    movie: Movie = {'name': 'Blade Runner',
                    'year': 1982}
    
    7, như được thảo luận bên dưới và đây không phải là cú pháp hợp lệ trong Python 2. 7. ] Thay vào đó, PEP này cung cấp một cú pháp thay thế, dựa trên nhiệm vụ để tương thích ngược, được thảo luận trong Cú pháp thay thế
  • Các tham chiếu chuyển tiếp theo nghĩa đen của chuỗi hợp lệ trong các loại giá trị
  • Các phương thức không được phép, vì kiểu thời gian chạy của đối tượng TypedDict sẽ luôn chỉ là
    movie: Movie = {'name': 'Blade Runner',
                    'year': 1982}
    
    8 [nó không bao giờ là lớp con của
    movie: Movie = {'name': 'Blade Runner',
                    'year': 1982}
    
    8]
  • Chỉ định một siêu dữ liệu không được phép

Có thể tạo một TypedDict trống bằng cách chỉ bao gồm

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
30 trong phần nội dung [nếu có một chuỗi tài liệu, có thể bỏ qua
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
30]

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
2

Sử dụng các loại TypedDict

Dưới đây là một ví dụ về cách sử dụng loại

movie: Movie = {'name': 'Blade Runner',
                'year': 1982}
0

movie: Movie = {'name': 'Blade Runner',
                'year': 1982}

Nói chung, cần có một chú thích loại

movie: Movie = {'name': 'Blade Runner',
                'year': 1982}
0 rõ ràng, vì nếu không thì một loại từ điển thông thường có thể được giả định bởi trình kiểm tra loại, để tương thích ngược. Khi một trình kiểm tra kiểu có thể suy luận rằng một đối tượng từ điển được xây dựng phải là một TypedDict, thì có thể bỏ qua một chú thích rõ ràng. Một ví dụ điển hình là một đối tượng từ điển làm đối số hàm. Trong ví dụ này, một trình kiểm tra kiểu dự kiến ​​sẽ suy luận rằng đối số từ điển phải được hiểu là một TypedDict

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
3

Một ví dụ khác trong đó trình kiểm tra kiểu sẽ coi màn hình từ điển là TypedDict trong một phép gán cho một biến có kiểu TypedDict đã khai báo trước đó

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
0

Các hoạt động trên

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
4 có thể được kiểm tra bằng trình kiểm tra kiểu tĩnh

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
2

Mã bên dưới nên bị từ chối, vì

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
35 không phải là khóa hợp lệ và khóa
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
7 bị thiếu

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
5

Đối tượng kiểu TypedDict đã tạo không phải là đối tượng lớp thực. Dưới đây là những cách sử dụng duy nhất của loại mà trình kiểm tra loại dự kiến ​​sẽ cho phép

  • Nó có thể được sử dụng trong chú thích loại và trong bất kỳ ngữ cảnh nào mà gợi ý loại tùy ý là hợp lệ, chẳng hạn như trong bí danh loại và là loại mục tiêu của một diễn viên
  • Nó có thể được sử dụng như một đối tượng có thể gọi được với các đối số từ khóa tương ứng với các mục TypedDict. Đối số không phải từ khóa không được phép. Thí dụ

    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    0

    Khi được gọi, đối tượng kiểu TypedDict trả về một đối tượng từ điển thông thường khi chạy

    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    1

  • Nó có thể được sử dụng như một lớp cơ sở, nhưng chỉ khi định nghĩa một TypedDict dẫn xuất. Điều này được thảo luận chi tiết hơn dưới đây

Cụ thể, các đối tượng kiểu TypedDict không thể được sử dụng trong các thử nghiệm

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
37 chẳng hạn như
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
38. Lý do là không có hỗ trợ hiện có để kiểm tra các loại giá trị mục từ điển, vì
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
37 không hoạt động với nhiều loại PEP 484, bao gồm cả những loại phổ biến như
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
00. Điều này sẽ cần thiết cho những trường hợp như thế này

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
2

Trường hợp sử dụng trên không được hỗ trợ. Điều này phù hợp với cách

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
37 không được hỗ trợ cho
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
00

Di sản

Loại TypedDict có thể kế thừa từ một hoặc nhiều loại TypedDict bằng cú pháp dựa trên lớp. Trong trường hợp này, không nên bao gồm lớp cơ sở

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
3. Thí dụ

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
3

Bây giờ

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
04 có khóa
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
05,
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
06 và
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
07. Nó tương đương với định nghĩa này, vì các loại TypedDict sử dụng khả năng tương thích cấu trúc

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
4

Đây là một ví dụ về đa kế thừa

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
5

TypedDict

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
08 có ba mục.
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
09 [loại
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
20],
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
21 [loại
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
8] và
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
23 [loại
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
24]

Một TypedDict không thể kế thừa từ cả TypedDict type và non-TypedDict lớp cơ sở

Ghi chú bổ sung về kế thừa lớp TypedDict

  • Không được phép thay đổi loại trường của lớp TypedDict cha trong lớp con. Thí dụ

    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    6

    Trong ví dụ nêu trên, các chú thích của lớp TypedDict trả về loại

    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    8 cho khóa
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    09

    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    7

  • Nhiều kế thừa không cho phép các loại xung đột đối với trường cùng tên

    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    8

toàn bộ

Theo mặc định, tất cả các khóa phải có trong TypedDict. Có thể ghi đè điều này bằng cách chỉ định tổng số. Đây là cách thực hiện việc này bằng cú pháp dựa trên lớp

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
9

Điều này có nghĩa là một

movie: Movie = {'name': 'Blade Runner',
                'year': 1982}
0 TypedDict có thể bỏ qua bất kỳ phím nào. Vì vậy, đây là hợp lệ

movie: Movie = {'name': 'Blade Runner',
                'year': 1982}
0

Trình kiểm tra loại chỉ được mong đợi để hỗ trợ một chữ

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
28 hoặc
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
29 làm giá trị của đối số
movie: Movie = {'name': 'Blade Runner',
                'year': 1982}
7.
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
29 là mặc định và bắt buộc phải có tất cả các mục được xác định trong nội dung lớp

Cờ tổng số chỉ áp dụng cho các mục được xác định trong phần nội dung của định nghĩa TypedDict. Các mục kế thừa sẽ không bị ảnh hưởng và thay vào đó sử dụng toàn bộ loại TypedDict nơi chúng được xác định. Điều này giúp có thể kết hợp các khóa bắt buộc và không bắt buộc trong một loại TypedDict duy nhất

Cú pháp thay thế

PEP này cũng đề xuất một cú pháp thay thế có thể được nhập vào các phiên bản Python cũ hơn, chẳng hạn như 3. 5 và 2. 7 không hỗ trợ cú pháp định nghĩa biến được giới thiệu trong PEP 526. Nó giống với cú pháp truyền thống để xác định các bộ dữ liệu có tên

movie: Movie = {'name': 'Blade Runner',
                'year': 1982}
1

Cũng có thể chỉ định tính toàn bộ bằng cách sử dụng cú pháp thay thế

movie: Movie = {'name': 'Blade Runner',
                'year': 1982}
2

Ngữ nghĩa tương đương với cú pháp dựa trên lớp. Tuy nhiên, cú pháp này không hỗ trợ kế thừa và không có cách nào để có cả trường bắt buộc và trường không bắt buộc trong một loại. Động lực cho điều này là giữ cho cú pháp tương thích ngược càng đơn giản càng tốt trong khi bao gồm các trường hợp sử dụng phổ biến nhất

Trình kiểm tra loại chỉ được phép chấp nhận biểu thức hiển thị từ điển làm đối số thứ hai cho

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
3. Đặc biệt, một biến tham chiếu đến một đối tượng từ điển không cần được hỗ trợ, để đơn giản hóa việc thực hiện

Loại nhất quán

Nói một cách không chính thức, tính nhất quán của loại là sự tổng quát hóa của quan hệ is-subtype-of để hỗ trợ loại

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
53. Nó được định nghĩa chính thức hơn trong PEP 483. Phần này giới thiệu các quy tắc mới, không tầm thường cần thiết để hỗ trợ tính nhất quán của loại cho các loại TypedDict

Đầu tiên, mọi loại TypedDict đều phù hợp với

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
54. Thứ hai, loại TypedDict
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
55 phù hợp với TypedDict
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
56 nếu
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
55 tương thích về mặt cấu trúc với
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
56. Điều này đúng khi và chỉ khi cả hai điều kiện này được thỏa mãn

  • Đối với mỗi khóa trong
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    56,
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    55 có khóa tương ứng và loại giá trị tương ứng trong
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    55 nhất quán với loại giá trị trong
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    56. Đối với mỗi khóa trong
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    56, loại giá trị trong
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    56 cũng nhất quán với loại giá trị tương ứng trong
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    55
  • Đối với mỗi khóa được yêu cầu trong
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    56, khóa tương ứng được yêu cầu trong
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    55. Đối với mỗi khóa không bắt buộc trong
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    56, khóa tương ứng không bắt buộc trong
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    55

Thảo luận

  • Các loại giá trị hoạt động bất biến, vì các đối tượng TypedDict có thể thay đổi. Điều này tương tự với các loại vùng chứa có thể thay đổi như
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    10 và
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    11. Ví dụ nơi này có liên quan

    movie: Movie = {'name': 'Blade Runner',
                    'year': 1982}
    
    3

  • Loại TypedDict có khóa bắt buộc không phù hợp với loại TypedDict trong đó cùng một khóa là khóa không bắt buộc, vì loại sau cho phép xóa khóa. Ví dụ nơi này có liên quan

    movie: Movie = {'name': 'Blade Runner',
                    'year': 1982}
    
    4

  • Loại TypedDict
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    55 không có khóa
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    13 không nhất quán với loại TypedDict có khóa không bắt buộc
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    13, vì trong thời gian chạy, khóa
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    13 có thể xuất hiện và có loại không tương thích [có thể không hiển thị thông qua
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    55 do phân nhóm cấu trúc]. Thí dụ

    movie: Movie = {'name': 'Blade Runner',
                    'year': 1982}
    
    5

  • TypedDict không phù hợp với bất kỳ loại
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    17 nào, vì các loại từ điển cho phép các hoạt động phá hoại, bao gồm cả
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    18. Chúng cũng cho phép đặt các khóa tùy ý, điều này sẽ ảnh hưởng đến sự an toàn của loại. Thí dụ

    movie: Movie = {'name': 'Blade Runner',
                    'year': 1982}
    
    6

  • Một TypedDict có tất cả các giá trị
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    20 không nhất quán với
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    20, vì có thể có các giá trị khác không phải
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    20 không hiển thị trong loại do phân loại cấu trúc. Chúng có thể được truy cập bằng cách sử dụng các phương pháp
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    22 và
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    23 trong
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    24, ví dụ. Thí dụ

    movie: Movie = {'name': 'Blade Runner',
                    'year': 1982}
    
    7

Hoạt động được hỗ trợ và không được hỗ trợ

Trình kiểm tra loại phải hỗ trợ các dạng bị hạn chế của hầu hết các hoạt động

movie: Movie = {'name': 'Blade Runner',
                'year': 1982}
8 trên các đối tượng TypedDict. Nguyên tắc hướng dẫn là các hoạt động không liên quan đến loại
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
53 nên bị từ chối bởi trình kiểm tra loại nếu chúng có thể vi phạm an toàn loại thời gian chạy. Dưới đây là một số loại vi phạm an toàn quan trọng nhất để ngăn chặn

  1. Một khóa bắt buộc bị thiếu
  2. Một giá trị có loại không hợp lệ
  3. Đã thêm khóa không được xác định trong loại TypedDict

Một khóa không phải là chữ thường sẽ bị từ chối, vì giá trị của nó không được biết trong quá trình kiểm tra loại và do đó có thể gây ra một số vi phạm ở trên. [Việc sử dụng các giá trị cuối cùng và các loại chữ tổng quát điều này để bao gồm các tên cuối cùng và các loại chữ. ]

Việc sử dụng khóa không được biết là tồn tại sẽ được báo cáo là lỗi, ngay cả khi điều này không nhất thiết tạo ra lỗi loại thời gian chạy. Đây thường là những lỗi và chúng có thể chèn các giá trị có loại không hợp lệ nếu phân nhóm cấu trúc ẩn các loại của một số mục nhất định. Ví dụ:

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
27 sẽ tạo ra lỗi kiểm tra loại nếu
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
13 không phải là khóa hợp lệ cho
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
26 [được giả định là loại TypedDict]

Các khóa bổ sung có trong cấu trúc đối tượng TypedDict cũng sẽ bị bắt. Trong ví dụ này, khóa

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
30 không được xác định trong
movie: Movie = {'name': 'Blade Runner',
                'year': 1982}
0 và dự kiến ​​sẽ tạo ra lỗi từ trình kiểm tra loại

movie: Movie = {'name': 'Blade Runner',
                'year': 1982}
8

Trình kiểm tra loại nên từ chối các thao tác sau trên đối tượng TypedDict là không an toàn, mặc dù chúng hợp lệ đối với từ điển thông thường

  • Các hoạt động với các khóa
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    8 tùy ý [thay vì chuỗi ký tự hoặc các biểu thức khác có giá trị chuỗi đã biết] thường bị từ chối. Điều này liên quan đến cả hoạt động phá hoại, chẳng hạn như đặt mục và hoạt động chỉ đọc, chẳng hạn như biểu thức đăng ký. Là một ngoại lệ đối với quy tắc trên, nên cho phép
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    33 và
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    34 đối với các đối tượng TypedDict, đối với một biểu thức tùy ý
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    35 với loại
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    8. Động lực là những thứ này an toàn và có thể hữu ích cho việc xem xét nội tâm các đối tượng TypedDict. Loại tĩnh của
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    33 phải là
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    38 nếu giá trị chuỗi của
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    35 không thể được xác định tĩnh
  • from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    18 không an toàn vì nó có thể xóa các khóa bắt buộc, một số trong số đó có thể không hiển thị trực tiếp do phân loại cấu trúc.
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    41 không an toàn tương tự, ngay cả khi không yêu cầu tất cả các khóa đã biết [
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    42]
  • from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    43 nên bị từ chối trừ khi
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    44 là khóa không bắt buộc

Bộ kiểm tra loại có thể cho phép đọc một mục bằng cách sử dụng

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
45 ngay cả khi không yêu cầu khóa
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
13, thay vì yêu cầu sử dụng
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
47 hoặc kiểm tra rõ ràng
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
48. Lý do là việc theo dõi sự tồn tại của các khóa rất khó thực hiện một cách tổng quát và việc không cho phép điều này có thể yêu cầu nhiều thay đổi đối với mã hiện có

Các quy tắc kiểm tra loại chính xác tùy thuộc vào từng trình kiểm tra loại để quyết định. Trong một số trường hợp, các hoạt động không an toàn tiềm ẩn có thể được chấp nhận nếu giải pháp thay thế là tạo ra lỗi dương tính giả cho mã thành ngữ

Sử dụng các giá trị cuối cùng và các loại chữ

Trình kiểm tra loại phải cho phép sử dụng tên cuối cùng [PEP 591] với giá trị chuỗi thay vì chuỗi ký tự trong các thao tác trên các đối tượng TypedDict. Ví dụ, điều này là hợp lệ

movie: Movie = {'name': 'Blade Runner',
                'year': 1982}
9

Tương tự, một biểu thức có kiểu chữ phù hợp [PEP 586] có thể được sử dụng thay cho giá trị bằng chữ

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
0

Trình kiểm tra loại chỉ được mong đợi hỗ trợ các chuỗi ký tự thực tế, không phải tên cuối cùng hoặc loại ký tự, để chỉ định các khóa trong định nghĩa loại TypedDict. Ngoài ra, chỉ có thể sử dụng một chữ boolean để chỉ định tính toàn bộ trong định nghĩa TypedDict. Động lực cho điều này là để làm cho các khai báo kiểu khép kín và để đơn giản hóa việc triển khai các trình kiểm tra kiểu.

Khả năng tương thích ngược

Để duy trì khả năng tương thích ngược, trình kiểm tra kiểu không nên suy ra kiểu TypedDict trừ khi nó đủ rõ ràng rằng lập trình viên mong muốn điều này. Khi không chắc chắn, nên suy ra một loại từ điển thông thường. Mặt khác, mã hiện tại kiểm tra loại không có lỗi có thể bắt đầu tạo lỗi sau khi hỗ trợ TypedDict được thêm vào trình kiểm tra loại, vì các loại TypedDict hạn chế hơn các loại từ điển. Đặc biệt, chúng không phải là kiểu con của các loại từ điển

Thực hiện tham khảo

Trình kiểm tra loại mypy [2] hỗ trợ các loại TypedDict. Việc triển khai tham chiếu của thành phần thời gian chạy được cung cấp trong mô-đun

from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
49 [3]. Việc triển khai ban đầu nằm trong mô-đun
from typing import TypedDict

class Movie[TypedDict]:
    name: str
    year: int
50 [4]

Lựa chọn thay thế bị từ chối

Nhiều ý tưởng đề xuất bị từ chối. Tập hợp các tính năng hiện tại dường như bao trùm rất nhiều nền tảng và không rõ tiện ích mở rộng nào được đề xuất sẽ hữu ích hơn một chút. PEP này xác định một tính năng cơ sở có thể được mở rộng sau này

Chúng bị từ chối về nguyên tắc, vì không phù hợp với tinh thần của đề xuất này

  • TypedDict không thể mở rộng và nó chỉ giải quyết một trường hợp sử dụng cụ thể. Các đối tượng TypedDict là các từ điển thông thường trong thời gian chạy và TypedDict không thể được sử dụng với các lớp giống như từ điển hoặc giống như ánh xạ khác, bao gồm các lớp con của
    movie: Movie = {'name': 'Blade Runner',
                    'year': 1982}
    
    8. Không có cách nào để thêm phương thức vào các loại TypedDict. Động lực ở đây là sự đơn giản
  • Các định nghĩa kiểu TypedDict có thể được sử dụng hợp lý để thực hiện kiểm tra kiểu thời gian chạy của từ điển. Ví dụ: chúng có thể được sử dụng để xác thực rằng đối tượng JSON tuân theo lược đồ được chỉ định bởi loại TypedDict. PEP này không bao gồm chức năng như vậy, vì trọng tâm của đề xuất này chỉ là kiểm tra kiểu tĩnh và các kiểu hiện có khác không hỗ trợ điều này, như đã thảo luận trong Cú pháp dựa trên lớp. Ví dụ, chức năng như vậy có thể được cung cấp bởi thư viện bên thứ ba bằng cách sử dụng mô-đun bên thứ ba
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    52 [5]
  • Loại TypedDict không thể được sử dụng trong kiểm tra
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    37 hoặc
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    54. Lý do tương tự như lý do tại sao kiểm tra loại thời gian chạy không được hỗ trợ nói chung với nhiều gợi ý loại

Các tính năng này đã bị loại khỏi PEP này, nhưng chúng là các tiện ích mở rộng tiềm năng sẽ được thêm vào trong tương lai

  • TypedDict không hỗ trợ cung cấp loại giá trị mặc định cho các khóa không được xác định rõ ràng. Điều này sẽ cho phép các khóa tùy ý được sử dụng với đối tượng TypedDict và chỉ những khóa được liệt kê rõ ràng mới được xử lý đặc biệt so với loại từ điển thống nhất, thông thường
  • Không có cách nào để chỉ định riêng từng khóa có được yêu cầu hay không. Không có cú pháp đề xuất nào đủ rõ ràng và chúng tôi hy vọng rằng có nhu cầu hạn chế đối với điều này
  • TypedDict không thể được sử dụng để chỉ định loại đối số
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    55. Điều này sẽ cho phép hạn chế các đối số từ khóa được phép và các loại của chúng. Theo PEP 484, sử dụng loại TypedDict làm loại
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    55 có nghĩa là TypedDict hợp lệ làm giá trị của các đối số từ khóa tùy ý, nhưng nó không hạn chế đối số từ khóa nào sẽ được cho phép. Cú pháp
    from typing import TypedDict
    
    class Movie[TypedDict]:
        name: str
        year: int
    
    57 đã được đề xuất cho việc này [6]

Sự nhìn nhận

David Foster đã đóng góp việc triển khai ban đầu các loại TypedDict cho mypy. Ít nhất tác giả [Jukka Lehtosalo], Ivan Levkivskyi, Gareth T, Michael Lee, Dominik Miedzinski, Roy Williams và Max Moroz đã đóng góp những cải tiến cho việc triển khai

Các đối tượng từ điển trong Python là gì?

Từ điển là Việc triển khai cấu trúc dữ liệu của Python thường được gọi là mảng kết hợp . Một từ điển bao gồm một tập hợp các cặp khóa-giá trị. Mỗi cặp khóa-giá trị ánh xạ khóa với giá trị được liên kết của nó.

Bạn có thể đặt các đối tượng trong từ điển Python không?

Kết luận. Không có phương thức add[] , append[] hoặc insert[] nào mà bạn có thể sử dụng để thêm một mục vào từ điển trong Python . Thay vào đó, bạn thêm một mục vào từ điển bằng cách chèn khóa chỉ mục mới vào từ điển, sau đó gán cho nó một giá trị cụ thể.

Những loại nào được phép cho các giá trị từ điển Python?

Trong từ điển, trong python, các giá trị có thể thuộc bất kỳ loại nào và có thể có bất kỳ giá trị nào nhưng các khóa là duy nhất. Các giá trị được lưu trữ có thể thuộc bất kỳ loại nào, chẳng hạn như từ điển, danh sách, bộ dữ liệu, danh sách từ điển, chuỗi hoặc số nguyên, nhưng các khóa chỉ thuộc loại dữ liệu bất biến.

Chủ Đề