You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为transaction函数添加类型注解,使类型检查器能推导返回值类型?

How to Add Type Annotations to a Transaction Function for Proper Type Inference

Great question! To make your transaction function play nicely with type checkers (like mypy or Pyright) and correctly infer the return type based on the input type tuple, you'll want to leverage variadic generics (available in Python 3.10+ via the standard library, or in older versions with typing_extensions). Here's a step-by-step breakdown:

Step 1: Import Required Typing Utilities

First, grab the tools needed to handle variable-length type tuples:

# For Python 3.10+ (standard library)
from typing import TypeVarTuple, Unpack, Tuple, Protocol

# For Python 3.9 or earlier, install typing_extensions first:
# from typing_extensions import TypeVarTuple, Unpack

Step 2: Define Generic Type Variables

We'll use a TypeVarTuple to capture the arbitrary set of types passed to the function. Optionally, add a protocol to enforce that input types support your deserialization logic:

# Define a variadic type variable to represent our input type tuple
Ts = TypeVarTuple('Ts')

# Optional: Protocol to ensure types can be deserialized (adjust to your needs)
class Deserializable(Protocol):
    @classmethod
    def from_dict(cls, data: dict) -> "Deserializable":
        """Required method for deserializing from raw transaction data"""
        ...

If you want to enforce that all input types follow this deserialization rule, update the TypeVarTuple with a bound:

Ts = TypeVarTuple('Ts', bound=Deserializable)

Step 3: Annotate the Transaction Function

Link the input type tuple directly to the return type tuple so type checkers can map them 1:1:

Case 1: Function accepts variable positional arguments (e.g., transaction(User, Order))

def transaction(*types: Unpack[Tuple[Unpack[Ts]]]) -> Tuple[Unpack[Ts]]:
    # Simulate transaction execution and raw data retrieval
    # In real code, replace this with your actual transaction logic
    raw_transaction_data = [{"user_id": 1}, {"order_id": 100}]
    
    # Deserialize each data entry into the corresponding type instance
    result = []
    for cls, data in zip(types, raw_transaction_data):
        # Use your actual deserialization logic here
        instance = cls.from_dict(data)  # Uses the Deserializable protocol
        # Or cls(**data) if your type accepts kwargs in __init__
        result.append(instance)
    
    return tuple(result)

Case 2: Function accepts a single tuple argument (e.g., transaction(types=(User, Order)))

If your function takes a tuple parameter instead of positional args, adjust the annotation like this:

def transaction(types: Tuple[Unpack[Ts]]) -> Tuple[Unpack[Ts]]:
    # Same implementation as above
    ...

Step 4: Test the Type Inference

When you use the function, type checkers will automatically infer the correct return type:

class User(Deserializable):
    def __init__(self, user_id: int):
        self.user_id = user_id
    
    @classmethod
    def from_dict(cls, data: dict) -> "User":
        return cls(user_id=data["user_id"])

class Order(Deserializable):
    def __init__(self, order_id: int):
        self.order_id = order_id
    
    @classmethod
    def from_dict(cls, data: dict) -> "Order":
        return cls(order_id=data["order_id"])

# Type checker infers this returns Tuple[User, Order]
user, order = transaction(User, Order)

# Type checkers will flag errors if you try to assign to the wrong type
wrong_type: str = user  # Mypy/Pyright will throw an error here

Key Notes

  • Type Checker Support: Ensure you're using a tool that supports variadic generics (mypy 0.910+, Pyright, or PyCharm 2021.3+).
  • Older Python Versions: For Python 3.9 or earlier, install typing_extensions and import TypeVarTuple/Unpack from there instead of typing.
  • Flexibility: This approach works for any number of input types—whether you pass 1, 5, or 10 types, the return type will match exactly.

内容的提问来源于stack exchange,提问作者Andrey Cizov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:27:30