gpt4 book ai didi

python-3.x - Python 动态类型提示

转载 作者:行者123 更新时间:2023-12-03 15:50:55 25 4
gpt4 key购买 nike

我希望能够提供一个具有类型元组的函数,然后将其用于反序列化从事务返回的数据。如果事务成功,该函数将返回这些类型的实例。
例如:

T = TypeVar('T')

class Base:
@classmethod
def deserialize(cls: Type[T], bts: bytes) -> T:
return cls(**json.loads(bts))

@classmethod
def transaction(cls, *types):
items = self.db.transact([t.generate_load_operation() for t in types])
items = [t.deserialize(item) for item in items]

# how do I type-hint transaction, so that it would imply that
# it will always return a tuple (or a list) of instances of classes
# contained in variable types?
return items

class A(Base):
pass

class B(Base):
pass

a_inst, b_inst = Base.transaction(A, B)

我应该如何注释事务,以便类型检查器可以正确推断从它返回的值的类型?

最佳答案

没有通用的方法来做到这一点:可变参数,例如 *types就静态类型检查而言,不要保留顺序。 Variadic generics cover this behaviour but are only proposals so far .
可以将单个注释用于可变参数,这会降级为通用基本类型,也可以使用需要枚举最常见情况的多个注释。

将可变参数注释为类型变量(可能通过 Base 绑定(bind))。这会将所有类型推断为相同的最常见的基本类型。

class Base:
@classmethod
def transaction(cls, *types: Type[T]) -> List[T]: ...

class A(Base): ...

class B(Base): ...

reveal_type(Base.transaction(A, A)) # builtins.list[mt.A*]
reveal_type(Base.transaction(A, B)) # builtins.list[mt.Base*]
这在使用类似类型(例如,仅 AA 的子类)并且仅期望一般特征(例如,仅 A )时就足够了。这在使用混合类型(例如 AB )时是不够的,因为它会退化为通用基本类型(例如 Base )。

提供 multiple @overload 合理数量的参数的签名,并为大量参数使用可变参数包罗万象。这将为指定的情况推断出正确的类型,否则使用最常见的基本类型。

class Base:
# explicitly enumerated types
@overload
@classmethod
def transaction(cls, t1: Type[T1], /) -> Tuple[T1]: ...
@overload
@classmethod
def transaction(cls, t1: Type[T1], t2: Type[T2], /) -> Tuple[T1, T2]: ...
# catch all number of types
@overload
@classmethod
def transaction(cls, *ts: Type[T]) -> Tuple[T, ...]: ...

# implementation
@classmethod
def transaction(cls, *types: Type[T]) -> Tuple[T, ...]: ...

class A(Base): ...

class B(Base): ...

reveal_type(Base.transaction(A)) # Revealed type is 'Tuple[mt.A*]'
reveal_type(Base.transaction(A, A)) # Revealed type is 'Tuple[mt.A*, mt.A*]'
reveal_type(Base.transaction(A, B)) # Revealed type is 'Tuple[mt.A*, mt.B*]'
reveal_type(Base.transaction(A, B, A)) # Revealed type is 'builtins.tuple[mt.Base*]'
这里的限制只是有多少案例被认为是相关的。 This mechanism is also used for the standard library.

关于python-3.x - Python 动态类型提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49018605/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com