我想暗示变量的类型作为特定函数的返回类型(无需手动指定函数的返回类型)。
我无法以可以用作其他变量提示的方式从函数中提取返回值类型。
def dostuff() -> T:
StuffContainer = namedtuple("StuffContainer", ["x", "y"])
return StuffContainer(1, 2)
def getX(a : T):
return a.x
相当于我想做的事的C ++:
auto dostuff() {
struct data {
int x;
int y;
};
return data {1, 2};
}
int getX(decltype(dostuff()) a) {
return a.x;
}
答案 0 :(得分:2)
在PEP 484打字生态系统中没有与decltype
等效的文件。更广泛地说,实际上没有一种很好的方式来表达“匿名”类型。
因此,您键入代码的规范方法是执行以下操作:
StuffContainer = namedtuple("StuffContainer", ["x", "y"])
def dostuff() -> StuffContainer:
return StuffContainer(1, 2)
def getX(a: StuffContainer):
return a.x
如果您担心返回的类型太长且不方便写出来,则可以使用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
进行编码,则返回特定的 一个namedtuple,而您只想返回一个带有'x'和' y'属性,您也许可以使用协议-您可以在in the PEP和mypy docs中找到有关协议的更多信息。 (不幸的是,尽管在正式的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))
答案 1 :(得分:0)
我不确定我是否真的喜欢这个,但是你可以做到。
方法的类型提示存储在注释中,因此您可以动态编辑它们。
In [25]: class T:
...: x: int
...: y: str
...:
In [26]: def dostuff() -> T:
...: pass
...:
In [27]: def getX(a: T):
...: pass
...:
In [28]: getX
Out[28]: <function __main__.getX(a: __main__.T)>
In [29]: getX.__annotations__['return']=T.__annotations__['x']
In [30]: getX
Out[30]: <function __main__.getX(a: __main__.T) -> int>
我真的不认为这是您的意思,但是也许。