在另一个泛型类型中使用泛型类型的参数
Using an Argument to a Generic Type in Another Generic Type
标题可能有点含糊,因为我不确定如何准确表达我想做的事情。
我想在 python:
中从 C++ 复制类似的模式
template<typename T>
struct Foo
{
using t = T; // Alias T so it can be used in Bar
};
template<typename T>
struct Bar
{
// The type T from Foo<T> can be used as a return type here
typename T::t fn()
{
// do something that returns T::t
}
};
int main(){
// x is determined to be a float
auto x = Bar<Foo<float>>().fn();
};
就 python 而言,我想用另一种特殊类型 Foo[T]
专门化泛型类型 Bar[T]
,然后使用用于专门化 Foo
的类型] 在 Bar
.
中键入提示
类似
from typing import TypeVar, Generic
T = TypeVar("T")
class Foo(Generic[T]):
...
class Bar(Generic[Foo[T]]): # <-- This is illegal
def fn(self) -> T:
...
# In the following, I would like the type checker to know that x is an int.
x = Bar[Foo[int]]().fn()
我知道在创建 Bar
的实例时可以推导出这种关系,如果我们有类似
class Bar(Generic[T]):
def __init__(self, foo: Foo[T]):
...
但这并不完全符合我目前的问题。
我宁愿能够创建一系列专业 Foo[T]
、Bar[T]
、Baz[T]
等,而无需重复 T
多次。在我的实际用例中,类型更像是 Foo[R, S, T]
并且重复类型非常乏味且容易出错,并且从概念上讲,类 Bar
、Baz
等被认为是不是取决于类型 T
而是取决于特定类型的 Foo[T]
.
所以如果有能力做这样的事情就好了
MyFoo = Foo[int]
MyBar = Bar[MyFoo]
MyBaz = Baz[MyFoo]
阅读 mypy 文档时,我遇到了这个:Advanced uses of self-types
通过在 Bar
中使用由 Foo
界定的 TypeVar
,我们可以指定 Bar
由类似 Foo
的东西参数化。然后,在各个方法中,我们可以使用嵌套类型 Bar[Foo[T]]
注释 self
,导致 T
绑定到参数化 Foo
参数化 Bar
的参数。
from __future__ import annotations
from typing import TypeVar, Generic
T = TypeVar("T")
class Foo(Generic[T]):
...
# You may want to make `S` covariant with `covariant=True`
# if you plan on using subclasses of `Foo` as parameters to `Bar`.
S = TypeVar("S", bound=Foo)
class Bar(Generic[S]):
def fn(self: Bar[Foo[T]]) -> T:
...
# Below, when binding `fn`, `self` is recognized as
# being of type `Bar[Foo[int]]` which binds `T` as `int`
# and hence the return type is also `int`.
x = Bar[Foo[int]]().fn()
我一直想不通的是如何使用Bar[Foo[T]]
中的参数T
来注释Bar
的一个属性。像
class Bar(Generic[Foo[T]]): # Still invalid.
item: T
窗台不起作用。
但是,可以通过将属性包装在 属性
中来解决这个问题
class Bar(Generic[S]):
_item: Any
@property
def item(self: Bar[Foo[T]]) -> T:
return self._item
以 _item
的类型提示不精确为代价。
标题可能有点含糊,因为我不确定如何准确表达我想做的事情。
我想在 python:
中从 C++ 复制类似的模式template<typename T>
struct Foo
{
using t = T; // Alias T so it can be used in Bar
};
template<typename T>
struct Bar
{
// The type T from Foo<T> can be used as a return type here
typename T::t fn()
{
// do something that returns T::t
}
};
int main(){
// x is determined to be a float
auto x = Bar<Foo<float>>().fn();
};
就 python 而言,我想用另一种特殊类型 Foo[T]
专门化泛型类型 Bar[T]
,然后使用用于专门化 Foo
的类型] 在 Bar
.
类似
from typing import TypeVar, Generic
T = TypeVar("T")
class Foo(Generic[T]):
...
class Bar(Generic[Foo[T]]): # <-- This is illegal
def fn(self) -> T:
...
# In the following, I would like the type checker to know that x is an int.
x = Bar[Foo[int]]().fn()
我知道在创建 Bar
的实例时可以推导出这种关系,如果我们有类似
class Bar(Generic[T]):
def __init__(self, foo: Foo[T]):
...
但这并不完全符合我目前的问题。
我宁愿能够创建一系列专业 Foo[T]
、Bar[T]
、Baz[T]
等,而无需重复 T
多次。在我的实际用例中,类型更像是 Foo[R, S, T]
并且重复类型非常乏味且容易出错,并且从概念上讲,类 Bar
、Baz
等被认为是不是取决于类型 T
而是取决于特定类型的 Foo[T]
.
所以如果有能力做这样的事情就好了
MyFoo = Foo[int]
MyBar = Bar[MyFoo]
MyBaz = Baz[MyFoo]
阅读 mypy 文档时,我遇到了这个:Advanced uses of self-types
通过在 Bar
中使用由 Foo
界定的 TypeVar
,我们可以指定 Bar
由类似 Foo
的东西参数化。然后,在各个方法中,我们可以使用嵌套类型 Bar[Foo[T]]
注释 self
,导致 T
绑定到参数化 Foo
参数化 Bar
的参数。
from __future__ import annotations
from typing import TypeVar, Generic
T = TypeVar("T")
class Foo(Generic[T]):
...
# You may want to make `S` covariant with `covariant=True`
# if you plan on using subclasses of `Foo` as parameters to `Bar`.
S = TypeVar("S", bound=Foo)
class Bar(Generic[S]):
def fn(self: Bar[Foo[T]]) -> T:
...
# Below, when binding `fn`, `self` is recognized as
# being of type `Bar[Foo[int]]` which binds `T` as `int`
# and hence the return type is also `int`.
x = Bar[Foo[int]]().fn()
我一直想不通的是如何使用Bar[Foo[T]]
中的参数T
来注释Bar
的一个属性。像
class Bar(Generic[Foo[T]]): # Still invalid.
item: T
窗台不起作用。
但是,可以通过将属性包装在 属性
中来解决这个问题class Bar(Generic[S]):
_item: Any
@property
def item(self: Bar[Foo[T]]) -> T:
return self._item
以 _item
的类型提示不精确为代价。