•21 min read

Các mẫu Chế độ Nghiêm ngặt Mypy Nâng cao cho Python Sản xuất

Các mẫu Chế độ Nghiêm ngặt Mypy Nâng cao cho Python Sản xuất

Nếu bạn đã từng dành thời gian bảo trì một codebase Python lớn, bạn sẽ biết rằng typing không chỉ là một công cụ hỗ trợ tài liệu nữa—mà nó còn là thứ giúp máy chủ sản xuất của bạn không bị sập lúc 2 giờ sáng. Khi các dự án phát triển từ vài script thành hàng chục microservice, kiểu động trở thành một gánh nặng. Mypy giúp ích, nhưng theo mặc định, nó quá dễ dãi. Nếu bạn thực sự muốn phát hiện các lỗi tinh vi trước khi chúng đến sản xuất, các gợi ý kiểu cơ bản là không đủ.

Bạn cần chuyển mypy sang chế độ nghiêm ngặt. Nhưng làm điều đó trên một codebase thực tế có nghĩa là bạn sẽ nhanh chóng chạm đến giới hạn của các gợi ý kiểu tiêu chuẩn. Bạn sẽ cần sử dụng các cấu trúc nâng cao như ParamSpec, TypeVarTuple, Protocol và các vị từ TypeGuard tùy chỉnh. Hãy cùng xem cách thực sự sử dụng các tính năng này để xây dựng các ứng dụng Python an toàn kiểu, dễ bảo trì mà không phải đối phó với trình kiểm tra kiểu từng bước.

Audio Briefing
0:00 / 0:00

Tại sao phải bận tâm với Mypy nghiêm ngặt?

Khi mypy hoạt động ở chế độ mặc định, về cơ bản nó đang chơi ở chế độ dễ. Các hàm không được chú thích âm thầm chấp nhận Any, biến các kiểm tra kiểu được tạo cẩn thận của bạn thành một cảm giác an toàn sai lầm.

Cấu hình Mypy nghiêm ngặt

Khi mypy hoạt động ở chế độ mặc định, các hàm không được chú thích âm thầm chấp nhận các tham số Any, vô hiệu hóa kiểm tra kiểu tĩnh trên các ngăn xếp cuộc gọi hạ nguồn. Sự dự phòng ngầm định này tạo ra một cảm giác an toàn sai lầm, cho phép các lỗi thuộc tính bị thiếu và các kiểu đối số không hợp lệ đến máy chủ sản xuất. Bật cờ meta --strict của mypy kích hoạt hơn một tá quy tắc kiểm tra kiểu riêng lẻ yêu cầu định nghĩa kiểu rõ ràng cho mọi chữ ký hàm, xuất module và khai báo biến. Ở chế độ nghiêm ngặt, trình phân tích tĩnh từ chối các decorator không có kiểu, ngăn chặn các đối số kiểu một phần và gắn cờ các thể hiện chung không được chú thích ngay lập tức. Các tổ chức kỹ thuật áp dụng kiểm tra kiểu nghiêm ngặt giảm đáng kể tỷ lệ các ngoại lệ AttributeError thời gian chạy trong các hệ thống sản xuất. Nếu bạn không loại bỏ các định nghĩa hàm không có kiểu, các trình gọi hạ nguồn có thể truyền các thuộc tính payload không hợp lệ mà không kích hoạt cảnh báo biên dịch.

Cấu hình pyproject.toml cấp độ sản xuất thực thi các chính sách an toàn kiểu nghiêm ngặt trong khi cung cấp các ghi đè được kiểm soát cho các module kế thừa:

[tool.mypy]
python_version = "3.13"
strict = true
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
show_error_codes = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]

[[tool.mypy.overrides]]
module = "legacy_third_party_sdk.*"
ignore_missing_imports = true
disallow_untyped_defs = false

Cấu hình show_error_codes = true cho phép các nhà phát triển giải quyết các vi phạm kiểu cụ thể bằng cách sử dụng các nhận xét ngăn chặn nội tuyến khi tích hợp các thư viện của bên thứ ba:

# Inline type ignore comments must include specific error codes in strict mode
import untyped_vendor_library  # type: ignore[import-untyped]

def calculate_checksum(payload: bytes) -> str:
    # Explicit cast ensures mypy tracks the return type correctly
    result = untyped_vendor_library.hash_bytes(payload)
    return str(result)

Việc thực thi kiểm tra kiểu nghiêm ngặt ở cấp độ kho lưu trữ đảm bảo rằng tất cả các thành viên trong nhóm tuân thủ các tiêu chuẩn an toàn kiểu nhất quán trên mọi yêu cầu kéo. Đây là một chiến lược đã được chứng minh để xây dựng các nền tảng doanh nghiệp đáng tin cậy.

Ngoài ra, các cài đặt cấu hình mypy nghiêm ngặt ngăn chặn các lỗi đánh máy phổ biến như các tham số Optional ngầm định. Trong các thiết lập mypy không nghiêm ngặt, việc viết def process(data: str = None) ngầm định chuyển đổi data thành Optional[str], dẫn đến các lỗi NoneType không mong muốn khi người gọi truyền các đối số không được xác thực. Chế độ nghiêm ngặt gắn cờ no_implicit_optional = true yêu cầu các nhà phát triển viết các định nghĩa kiểu rõ ràng data: str | None = None, làm rõ chữ ký hàm cho các công cụ phân tích tĩnh và các thành viên trong nhóm. Tốt nhất là bắt buộc khai báo khả năng null rõ ràng trên tất cả các thực thể miền.

Ngoài ra, việc tích hợp các lượt kiểm tra mypy vào các hook git pre-commit đảm bảo rằng mã không có kiểu không thể được commit vào các nhánh được chia sẻ. Các nhà phát triển nhận được phản hồi tức thì trong môi trường terminal cục bộ của họ, phát hiện các lỗi không khớp kiểu trước khi kích hoạt các công việc xây dựng tích hợp liên tục dài. Nếu bạn không tự động hóa kiểm tra kiểu trong các hook git, các commit không được xác thực sẽ làm chậm các pipeline triển khai tự động.

Ngoài ra, việc cấu hình warn_unused_ignores = true tự động dọn dẹp các nhận xét # type: ignore cũ khi các stub thư viện cơ bản cập nhật. Cài đặt này ngăn các nhà phát triển tích lũy các dấu hiệu ngăn chặn lỗi thời trên các kho lưu trữ đơn lớn.

Ngoài ra, chế độ nghiêm ngặt buộc các nhà phát triển phải xử lý các trường tùy chọn một cách rõ ràng. Khi truy cập các thuộc tính lồng nhau trên các đối tượng có thể trả về None, các công cụ phân tích tĩnh yêu cầu các xác nhận bảo vệ rõ ràng, ngăn chặn các sự cố con trỏ null trong các dịch vụ web trực tiếp.

Cuối cùng, việc thực thi chế độ nghiêm ngặt đơn giản hóa việc tái cấu trúc tự động trên các kho lưu trữ đơn lớn. Khi các nhà phát triển sửa đổi các lược đồ cơ sở dữ liệu cốt lõi hoặc giao diện hàm, mypy gắn cờ mọi vị trí gọi bị ảnh hưởng trong toàn bộ codebase, cho phép các kỹ sư cập nhật các module phụ thuộc một cách tự tin mà không cần dựa vào các script tìm kiếm thủ công.

Advertisement

ParamSpec và TypeVarTuple định kiểu các Decorator hàm phức tạp như thế nào?

ParamSpec và TypeVarTuple định kiểu các decorator phức tạp bằng cách bảo toàn các kiểu chữ ký tham số chính xác và các chữ ký tuple biến đổi trên các trình bao hàm bậc cao hơn.

Decorator ParamSpec

Trong lịch sử, việc viết các decorator Python an toàn kiểu nổi tiếng là khó khăn vì các biến TypeVar truyền thống không thể nắm bắt danh sách tham số hàm với các kết hợp đối số tùy ý. Các hàm decorator thường quay trở lại sử dụng Callable[..., R], loại bỏ tên đối số, cờ từ khóa và các kiểu tham số mặc định khỏi chữ ký hàm được trang trí. Được giới thiệu trong PEP 612, ParamSpec nắm bắt toàn bộ chữ ký tham số có thể gọi, cho phép các hàm wrapper chuyển tiếp các đối số vị trí và từ khóa tùy ý trong khi vẫn giữ nguyên các gợi ý kiểu tĩnh chính xác. Các kiến trúc sư phần mềm thiết kế cổng API và cơ chế thử lại dựa nhiều vào ParamSpec để duy trì an toàn kiểu hoàn chỉnh. Nếu bạn không bảo toàn chữ ký tham số, việc gọi các hàm được bao bọc bằng các decorator không có kiểu sẽ che giấu các tên tham số không hợp lệ.

Đây là một decorator thử lại không đồng bộ cấp độ sản xuất hoàn chỉnh, được định kiểu bằng ParamSpec và TypeVar:

import asyncio
import functools
import logging
from typing import Callable, ParamSpec, TypeVar

P = ParamSpec("P")
R = TypeVar("R")

logger = logging.getLogger(__name__)

def async_retry(
    max_attempts: int = 3,
    delay_seconds: float = 1.0
) -> Callable[[Callable[P, asyncio.Future[R]]], Callable[P, asyncio.Future[R]]]:
    # Higher-order decorator preserving exact parameter signatures and return types
    def decorator(func: Callable[P, asyncio.Future[R]]) -> Callable[P, asyncio.Future[R]]:
        @functools.wraps(func)
        async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
            last_exception: Exception | None = None
            for attempt in range(1, max_attempts + 1):
                try:
                    return await func(*args, **kwargs)
                except Exception as exc:
                    last_exception = exc
                    logger.warning(f"Attempt {attempt} failed for {func.__name__}: {exc}")
                    if attempt < max_attempts:
                        await asyncio.sleep(delay_seconds)
            if last_exception is not None:
                raise last_exception
            raise RuntimeError("Retry loop exited unexpectedly without result")
        return wrapper  # type: ignore[return-value]
    return decorator

Khi các nhà phát triển áp dụng async_retry cho các hàm miền được định kiểu, mypy xác minh các kiểu đối số tại mọi vị trí gọi với độ chính xác hoàn chỉnh:

@async_retry(max_attempts=5, delay_seconds=0.5)
async def fetch_user_profile(user_id: int, include_deleted: bool = False) -> dict[str, str]:
    # Business logic implementation goes here
    return {"user_id": str(user_id), "status": "active"}

# Mypy correctly validates caller parameter types against original signature
async def execution_example() -> None:
    # Valid call: mypy passes
    profile = await fetch_user_profile(42, include_deleted=True)

Đối với các cấu trúc chung biến đổi như biến đổi mảng hoặc kích thước tensor, PEP 646 đã giới thiệu TypeVarTuple để nắm bắt các hình dạng tuple tùy ý một cách tĩnh, đảm bảo an toàn kiểu trên các hàm xử lý dữ liệu đa chiều.

Ngoài ra, ParamSpec cho phép định kiểu chính xác cho các decorator bộ nhớ đệm và các trình bao bọc giới hạn tốc độ. Khi lưu trữ kết quả truy vấn cơ sở dữ liệu đắt tiền, các decorator được kiểm tra kiểu bảo toàn tên tham số và giá trị đối số mặc định, cho phép các công cụ tự động hoàn thành IDE hiển thị các lời nhắc tham số chính xác cho các nhà phát triển. Điều cần thiết là phải định kiểu các trình bao bọc decorator để các gợi ý tham số của người gọi vẫn hiển thị đầy đủ.

Ngoài ra, TypeVarTuple đơn giản hóa việc xây dựng các pipeline tuple được định kiểu mạnh. Khi xâu chuỗi các phép biến đổi toán học hoặc các hàm ánh xạ dữ liệu, TypeVarTuple cho phép các công cụ phân tích tĩnh theo dõi các chuyển đổi kiểu phần tử trên các chỉ mục tuple mà không làm mất độ chính xác của kiểu.

Ngoài ra, việc kết hợp ParamSpec với Concatenate cho phép các nhà phát triển định kiểu các decorator chèn các tham số vị trí bổ sung (như xử lý kết nối cơ sở dữ liệu hoặc ngữ cảnh xác thực) vào chữ ký hàm được bao bọc một cách an toàn.

Ngoài ra, ParamSpec cho phép viết các hệ thống điều phối sự kiện được định kiểu mạnh. Khi đăng ký các trình xử lý sự kiện trên các kênh ứng dụng, các decorator xác minh rằng chữ ký trình nghe sự kiện khớp chính xác với các kiểu payload đã xuất bản.

Cuối cùng, việc sử dụng TypeVarTuple bên trong các thư viện tensor số loại bỏ các lỗi không khớp kích thước trong các hoạt động định hình lại mảng, cho phép các nhóm kỹ thuật dữ liệu phát hiện các lỗi hình dạng tensor tại thời điểm biên dịch thay vì trong các lượt đào tạo mô hình.

Các Giao thức Cấu trúc Thay thế Ghép nối Danh nghĩa trong Hệ thống Kiểu Python như thế nào?

Các giao thức cấu trúc thay thế kế thừa lớp danh nghĩa bằng cách cho phép các trình kiểm tra kiểu tĩnh xác minh giao diện đối tượng dựa trên kiểu duck mà không cần phân lớp rõ ràng.

Giao thức cấu trúc

Kiểu danh nghĩa yêu cầu các lớp phải kế thừa rõ ràng từ các giao diện cơ sở để thỏa mãn các kiểm tra kiểu tĩnh. Ngược lại, di sản động của Python dựa vào kiểu duck, nơi khả năng đối tượng phụ thuộc vào các phương thức hiện có hơn là hệ thống phân cấp kế thừa lớp. Kiểu cấu trúc, được triển khai thông qua typing.Protocol, thu hẹp khoảng cách này bằng cách định nghĩa các hợp đồng giao diện tĩnh. Bất kỳ lớp nào triển khai các thuộc tính và chữ ký phương thức bắt buộc đều thỏa mãn giao thức tự động mà không cần kế thừa từ một lớp cơ sở chung. Sự tách rời này cho phép các mẫu kiến trúc sạch sẽ trên các codebase doanh nghiệp. Nếu bạn không sử dụng các giao thức cho các trừu tượng dịch vụ, logic nghiệp vụ của bạn sẽ phụ thuộc chặt chẽ vào các triển khai cơ sở dữ liệu cụ thể.

Hãy xem xét một thư viện lưu trữ đa backend chấp nhận nhiều triển khai client cơ sở dữ liệu khác nhau mà không buộc kế thừa rõ ràng:

from typing import Protocol, runtime_checkable

@runtime_checkable
class DocumentStore(Protocol):
    # Structural protocol defining key value document storage interface
    async def get_document(self, doc_id: str) -> dict[str, str] | None:
        ...

    async def save_document(self, doc_id: str, payload: dict[str, str]) -> bool:
        ...

class MemoryStorageBackend:
    # Class implementing DocumentStore structural interface implicitly
    def __init__(self) -> None:
        self._store: dict[str, dict[str, str]] = {}

    async def get_document(self, doc_id: str) -> dict[str, str] | None:
        return self._store.get(doc_id)

    async def save_document(self, doc_id: str, payload: dict[str, str]) -> bool:
        self._store[doc_id] = payload
        return True

async def process_user_record(store: DocumentStore, user_id: str) -> None:
    data = await store.get_document(user_id)
    if data is not None:
        print(f"Loaded user document: {data}")

Vì MemoryStorageBackend thỏa mãn các chữ ký phương thức được định nghĩa trong DocumentStore, mypy xác thực việc truyền các thể hiện MemoryStorageBackend vào process_user_record mà không yêu cầu class MemoryStorageBackend(DocumentStore):.

Bảng tóm tắt sau đây so sánh kế thừa giao diện danh nghĩa với kiểu giao thức cấu trúc trên các khía cạnh kỹ thuật phần mềm chính:

Khía cạnh khả năngKế thừa lớp danh nghĩaGiao thức cấu trúc (typing.Protocol)
Yêu cầu ghép nốiCao (Yêu cầu phân lớp rõ ràng)Không (Khớp giao diện ngầm định)
Thích ứng bên thứ baKhó (Yêu cầu bộ điều hợp wrapper)Ngay lập tức (Định kiểu các lớp bên thứ ba hiện có)
Chi phí thời gian chạyNhẹ (Chi phí tra cứu MRO lớp cơ sở)Không (Giao thức bị xóa tại thời gian chạy)
Xác minh thời gian chạyĐược hỗ trợ thông qua isinstanceĐược hỗ trợ khi sử dụng @runtime_checkable
Kiểm tra chữ ký phương thứcĐược thực thi trong quá trình khởi tạo lớpĐược thực thi trong quá trình phân tích tĩnh

Sử dụng các giao thức tách rời logic miền khỏi các triển khai thư viện cụ thể, dẫn đến các kiến trúc phần mềm mô-đun dễ kiểm tra.

Ngoài ra, các giao thức có thể định nghĩa các thuộc tính chỉ đọc và đọc-ghi bằng cách sử dụng các decorator @property Python tiêu chuẩn. Điều này cho phép các nhà phát triển thực thi ngữ nghĩa truy cập thuộc tính một cách tĩnh mà không yêu cầu định nghĩa phương thức getter và setter. Nếu bạn chưa khai báo các quy tắc truy cập thuộc tính trong các giao thức của mình, người gọi có thể vô tình thay đổi các trường chỉ đọc.

Ngoài ra, các giao thức đệ quy cho phép định kiểu tĩnh cho các cấu trúc cây lồng nhau như tài liệu JSON hoặc các nút AST. Một giao thức đệ quy tham chiếu chính nó bên trong chữ ký phương thức, cho phép mypy xác thực các biểu đồ đối tượng lồng sâu một cách sạch sẽ.

Ngoài ra, các giao thức đơn giản hóa việc kiểm thử đơn vị bằng cách loại bỏ nhu cầu về các framework mock nặng nề. Các nhà phát triển có thể định nghĩa các lớp giả nhẹ trong bộ nhớ thỏa mãn trực tiếp các giao diện giao thức, giữ cho các kiểm thử đơn vị nhanh và xác định.

Ngoài ra, các giao thức hỗ trợ các tham số kiểu chung, cho phép các nhà phát triển xây dựng các trừu tượng kho lưu trữ an toàn kiểu (Repository[T]) hoạt động trên các mô hình miền đa dạng mà không cần khai báo giao diện trùng lặp.

Cuối cùng, việc trang trí các giao thức bằng @runtime_checkable cho phép kiểm tra isinstance() tiêu chuẩn tại thời gian chạy trong khi vẫn giữ nguyên các đảm bảo kiểm tra kiểu tĩnh. Khả năng kép này làm cho các giao thức trở nên lý tưởng cho các kiến trúc plugin nơi việc khám phá lớp động xảy ra tại thời điểm khởi động ứng dụng.

Custom TypeGuards và TypeIs Expressions Thu hẹp các Kiểu Union Động như thế nào?

Custom TypeGuards và TypeIs expressions thu hẹp các kiểu union động bằng cách khẳng định các vị từ kiểu trong các hàm boolean hướng dẫn mypy về các tinh chỉnh kiểu thời gian chạy.

Thu hẹp TypeGuard

Khi làm việc với các payload dữ liệu không đồng nhất như phản hồi JSON hoặc các kiểu union (User | Admin | Anonymous), các nhà phát triển phải thu hẹp các kiểu đối tượng chung trước khi truy cập các thuộc tính cụ thể. Mặc dù các kiểm tra isinstance() tiêu chuẩn xử lý việc thu hẹp cơ bản, các xác thực cấu trúc phức tạp yêu cầu các hàm trợ giúp boolean tùy chỉnh. Các hàm boolean tiêu chuẩn trả về bool, không thể thông báo cho mypy về các giả định kiểu đã thu hẹp bên trong các khối điều kiện. Được giới thiệu trong PEP 647 và được tinh chỉnh trong PEP 742 (TypeIs), các vị từ thu hẹp kiểu cho phép các hàm tiện ích hướng dẫn mypy về các tinh chỉnh kiểu một cách rõ ràng. Nếu bạn không sử dụng các hàm thu hẹp kiểu, bạn sẽ buộc phải viết các câu lệnh cast() không an toàn bỏ qua các kiểm tra an toàn tĩnh.

Đây là một so sánh thực tế cho thấy việc thu hẹp kiểu tùy chỉnh bằng cách sử dụng TypeGuard và TypeIs:

from typing import Any, TypeGuard, TypeIs, TypedDict

class APIUserPayload(TypedDict):
    user_id: int
    username: str
    email: str

def is_valid_user_payload(data: dict[str, Any]) -> TypeGuard[APIUserPayload]:
    # TypeGuard asserts that returning True proves data matches APIUserPayload structure
    return (
        isinstance(data.get("user_id"), int)
        and isinstance(data.get("username"), str)
        and isinstance(data.get("email"), str)
    )

def is_string_list(items: list[Any]) -> TypeIs[list[str]]:
    # TypeIs provides narrowed type refinements in both True and False conditional branches
    return all(isinstance(item, str) for item in items)

Áp dụng các hàm thu hẹp này bên trong các khối xử lý điều kiện cho phép kiểm tra kiểu nghiêm ngặt trên các payload dữ liệu động:

def process_incoming_payload(raw_json: dict[str, Any]) -> str:
    if is_valid_user_payload(raw_json):
        # Inside this branch, mypy narrows raw_json to APIUserPayload
        return f"User {raw_json['username']} with ID {raw_json['user_id']} verified"
    else:
        # Handling unverified fallback payload safely
        return "Invalid payload structure received"

Sử dụng TypeGuard và TypeIs loại bỏ các cuộc gọi cast() không an toàn, thay thế các khẳng định kiểu không được xác minh bằng các kiểm tra vị từ an toàn kiểu.

Ngoài ra, TypeIs cải thiện độ chính xác thu hẹp so với TypeGuard khi xử lý các kiểu union loại trừ lẫn nhau. Bởi vì TypeIs thu hẹp cả hai nhánh True và False, nếu is_string(x) trả về False cho x: str | int, mypy tự động thu hẹp x thành int trong khối else.

Ngoài ra, các hàm thu hẹp kiểu tùy chỉnh đơn giản hóa các lớp xác thực dữ liệu trong các ứng dụng web. Bằng cách đóng gói các khẳng định cấu trúc bên trong các hàm TypeGuard có thể tái sử dụng, các nhà phát triển tránh lặp lại các kiểm tra thuộc tính nội tuyến trên các trình xử lý tuyến API. Nếu bạn chưa tập trung các hàm vị từ kiểu của mình, logic xác thực trùng lặp sẽ dẫn đến các kiểm tra payload không nhất quán.

Ngoài ra, việc kết hợp TypeGuard với TypedDict cung cấp xác thực lược đồ nhẹ mà không cần thêm các phụ thuộc bên thứ ba nặng nề vào các kho lưu trữ microservice nhỏ.

Ngoài ra, các hàm thu hẹp kiểu cho phép xác thực các từ điển cấu hình động được tải từ các tệp YAML hoặc JSON, đảm bảo rằng các cài đặt ứng dụng đáp ứng các định nghĩa lược đồ bắt buộc trước khi khởi động.

Cuối cùng, việc sử dụng các hàm thu hẹp kiểu bên trong các quy trình xử lý lỗi cho phép các nhà phát triển kiểm tra chi tiết lỗi lồng nhau một cách an toàn mà không gây ra các ngoại lệ AttributeError không mong muốn trong quá trình ghi nhật ký ngoại lệ.

Advertisement

Bạn cũng có thể thích

Các câu hỏi thường gặp về các mẫu Mypy nâng cao

Sự khác biệt chính giữa TypeGuard và TypeIs trong kiểu Python là gì?

TypeGuard thu hẹp kiểu của một đối số trong nhánh True của một khối điều kiện mà không thu hẹp nhánh False. TypeIs cung cấp tính năng thu hẹp kiểu hai chiều, tinh chỉnh kiểu đối số trong cả nhánh True và False để khẳng định kiểu chính xác.

Tại sao mypy gắn cờ các decorator không có kiểu ở chế độ nghiêm ngặt?

Ở chế độ nghiêm ngặt, mypy thực thi disallow_untyped_decorators = true vì việc áp dụng một decorator không có kiểu cho một hàm được định kiểu có thể bao bọc callable trong một wrapper không có kiểu, loại bỏ thông tin kiểu khỏi các vòng lặp xác minh của người gọi.

Kiểu Self cải thiện việc xâu chuỗi phương thức trong hệ thống phân cấp lớp như thế nào?

Kiểu Self, được giới thiệu trong PEP 673, cho phép các phương thức trong các lớp cơ sở trả về một thể hiện của lớp con gọi thay vì lớp cơ sở, bảo toàn kiểu lớp con chính xác trong quá trình xâu chuỗi phương thức linh hoạt.

Các giao thức có thể định nghĩa các thuộc tính lớp có thể đọc và ghi không?

Có, các giao thức có thể định nghĩa các thuộc tính lớp bắt buộc cùng với chữ ký phương thức bằng cách khai báo các biến với chú thích kiểu rõ ràng bên trong phần thân giao thức.

Các nhóm phần mềm nên di chuyển các codebase Python kế thừa sang kiểm tra mypy nghiêm ngặt như thế nào?

Các nhóm nên áp dụng chiến lược di chuyển dần dần bằng cách cấu hình các cài đặt nghiêm ngặt trên toàn cầu trong pyproject.toml trong khi sử dụng các ghi đè trên mỗi module để bỏ nghiêm ngặt các thư mục kế thừa cho đến khi việc tái cấu trúc hoàn tất.

Tác động hiệu suất của các chú thích kiểu tĩnh đối với việc thực thi thời gian chạy là gì?

Các chú thích kiểu Python được đánh giá tại thời điểm nhập module và bị bỏ qua trong quá trình thực thi mã byte, dẫn đến không có chi phí hiệu suất thời gian chạy cho các ứng dụng đã biên dịch.

Share this article:

Stay Updated

Get the latest posts delivered straight to your inbox.

Free Developer Utilities

Free In-Browser Developer Tools

Clean AI CLI logs, build cron expressions, decode JWTs, and calculate chmod permissions offline.

Explore Tools
Advertisement