python 中类型提示的 "and" 运算符是什么?
What's "and" operator for type hints in python?
我要为几种类型的组合创建一个“类型别名”。我可以为大多数类型创建一个新的 class,但这会使代码太长并且类型检查器无法显示它。我正在寻找更好的选择。我们可以使用 Union
作为 A | B
但我需要 A & B
.
示例:
from typing import TypeVar
T = TypeVar('T')
class Identify:
id: int
def test_type_hints(obj: T) -> T & Identify: # This Line
obj.id = id(obj)
如果我能做到,怎么做?不然为什么?
您显示的代码实际上并未将 obj
转换为 Identify
的实例,因此您要求添加的类型提示会产生误导。在运行时调用 isinstance(obj, Identify)
将是错误的,并且没有类型检查声明会接受该对象作为 class.
的实例
如果您希望 Identify
类型不是期望您子 class 并创建它的实例的真实类型,而只是“具有 [=16 的对象”的指示符=] 属性”,那么你应该把它设为 typing.Protocol
。协议可以满足您的需求,它可以让您描述一个对象必须具有的特性,并且任何类型的任何此类对象都将在任何需要遵守协议的对象的地方被接受。
from typing import Protocol
class Identify(typing.Protocol):
id: int
class MyObj:
pass
o = MyObj()
print(isinstance(o, Identify)) # prints False
o.id = 2
print(isinstance(o, Identify)) # prints True now
虽然这并不能完全解决您的问题,因为 Python 类型提示中并没有真正的机制来动态声明类型的交集(它是 a requested feature for a long time)。一种可能适用于某些情况的粗略方法是丢弃旧的类型信息并仅保留协议的新知识,但这对于您的用例来说可能不够好:
def test_type_hints(obj: typing.Any) -> Identify:
obj.id = id(obj)
return obj
我要为几种类型的组合创建一个“类型别名”。我可以为大多数类型创建一个新的 class,但这会使代码太长并且类型检查器无法显示它。我正在寻找更好的选择。我们可以使用 Union
作为 A | B
但我需要 A & B
.
示例:
from typing import TypeVar
T = TypeVar('T')
class Identify:
id: int
def test_type_hints(obj: T) -> T & Identify: # This Line
obj.id = id(obj)
如果我能做到,怎么做?不然为什么?
您显示的代码实际上并未将 obj
转换为 Identify
的实例,因此您要求添加的类型提示会产生误导。在运行时调用 isinstance(obj, Identify)
将是错误的,并且没有类型检查声明会接受该对象作为 class.
如果您希望 Identify
类型不是期望您子 class 并创建它的实例的真实类型,而只是“具有 [=16 的对象”的指示符=] 属性”,那么你应该把它设为 typing.Protocol
。协议可以满足您的需求,它可以让您描述一个对象必须具有的特性,并且任何类型的任何此类对象都将在任何需要遵守协议的对象的地方被接受。
from typing import Protocol
class Identify(typing.Protocol):
id: int
class MyObj:
pass
o = MyObj()
print(isinstance(o, Identify)) # prints False
o.id = 2
print(isinstance(o, Identify)) # prints True now
虽然这并不能完全解决您的问题,因为 Python 类型提示中并没有真正的机制来动态声明类型的交集(它是 a requested feature for a long time)。一种可能适用于某些情况的粗略方法是丢弃旧的类型信息并仅保留协议的新知识,但这对于您的用例来说可能不够好:
def test_type_hints(obj: typing.Any) -> Identify:
obj.id = id(obj)
return obj