没有等同于decltype
在 PEP 484 打字生态系统中。更广泛地说,并没有真正表达“匿名”类型的好方法。
因此,键入代码的规范方式是执行类似以下操作:
StuffContainer = namedtuple("StuffContainer", ["x", "y"])
def dostuff() -> StuffContainer:
return StuffContainer(1, 2)
def getX(a: StuffContainer):
return a.x
如果担心您返回的类型太长并且不方便写出,您也许可以使用以下命令将其缩短一点类型别名 https://docs.python.org/3/library/typing.html#type-aliases:
StuffContainer = namedtuple("StuffContainer", ["x", "y"])
# S is now an alias of StuffContainer. The two types can be
# used interchangeably.
S = StuffContainer
def dostuff() -> S:
return StuffContainer(1, 2)
def getX(a: S):
return a.x
如果担心的是您不想对其进行编码dostuff
回报具体来说一个命名元组,并且您只想承诺返回带有“x”和“y”属性的某个对象,您也许可以使用协议——您可以找到有关它们的更多信息在政治公众教育中 https://www.python.org/dev/peps/pep-0544/并在mypy 文档 https://mypy.readthedocs.io/en/stable/protocols.html。 (不幸的是,尽管官方 Python 类型模块文档中还没有任何关于它们的信息。)
例如:
from typing import NamedTuple
# If you're using Python 3.8+, you can do:
from typing import Protocol
# If you want to support older versions of Python,
# run 'pip install typing_extensions' and do the below instead
from typing_extensions import Protocol
# Any type that has 'x' and 'y' attributes is compatible with this.
class HasXAndY(Protocol):
# Making these properties to declare that they're read-only,
# for maximum flexibility.
@property
def x(self) -> int: ...
@property
def y(self) -> int: ...
def dostuff() -> HasXAndY:
# Note: I'm switching to a version of namedtuple that lets me associate
# types with each field, mostly just for demonstration purposes. At runtime,
# it behaves identically to collections.namedtuple.
StuffContainer = NamedTuple("StuffContainer", [("x", int), ("y", int)])
return StuffContainer(1, 2)
def get_x(obj: HasXAndY) -> int:
return obj.x
# Type-checks
get_x(dostuff())
class Unrelated:
def __init__(self, x: int, y: int, z: int) -> None:
self.x = x
self.y = y
self.z = z
# Also type-checks
get_x(Unrelated(1, 2, 3))