python-3.x - Python Typing:创建一个具有泛型类型的类函数,并通过该类访问该类型
问题描述
我有一个发布者可以发布某种类型的消息:
T = TypeVar('T')
class Publisher(Generic[T]):
def __init__(self, topic: str) -> None:
self.__topic = topic
def publish(self, msg: T):
pass
# As an example, create a publisher that can publish ints
p = Publisher[int]("chatter")
p.publish(1)
这可行,并且发布函数具有正确的类型提示,但我希望能够使用get_type()
函数访问发布者的类型。
一种简单的方法是将消息类型传递给构造函数:
T = TypeVar('T')
class Publisher(Generic[T]):
def __init__(self, msg_type: type, topic: str) -> None:
self.__msg_type = msg_type
self.__topic = topic
def publish(self, msg: T):
pass
def get_type(self) -> type:
return self.__msg_type
p = Publisher[int](int, "chatter")
p.publish(1)
但这需要int
在一行中写两次,p = Publisher[int](int, "chatter")
这似乎有点笨拙和多余。
我尝试将发布者的创建包装在一个函数中,这样您就不必编写int
两次,但我遇到了一个问题:
T = TypeVar('T', bound=type)
class Publisher(Generic[T]):
def __init__(self, msg_type: type, topic: str) -> None:
self.__msg_type = msg_type
self.__topic = topic
def publish(self, msg: T):
pass
def get_type(self) -> type:
return self.__msg_type
def create_publisher(msg_type: T, topic: str) -> Publisher[T]:
return Publisher[T](msg_type, topic)
p = create_publisher(int, "hello")
p.publish(1) #Fails because its expecting Type[int], not an instance of an int
所以我需要的是一种在类型提示上下文中转换Type[x]
为的方法。x
基本上与做什么相反Type
。
例如,最后一个示例将变为:
T = TypeVar('T', bound=type)
class Publisher(Generic[T]):
def __init__(self, msg_type: type, topic: str) -> None:
self.__msg_type = msg_type
self.__topic = topic
def publish(self, msg: InstanceOf[T]):
pass
def get_type(self) -> type:
return self.__msg_type
def create_publisher(msg_type: T, topic: str) -> Publisher[T]:
return Publisher[T](msg_type, topic)
p = create_publisher(int, "hello")
p.publish(1)
但我不知道如何使InstanceOf
通用。
无论如何我可以做到这一点吗?或任何其他方式来获得我想要的功能,而不必int
在一行中写两次p = Publisher[int](int, "chatter")
编辑
这是另一种也不起作用的尝试,但应该澄清我正在尝试做的事情:
T = TypeVar('T')
class Publisher(Generic[T]):
def __init__(self, topic: str) -> None:
self.__topic = topic
def publish(self, msg: T):
pass
def get_type(self) -> type:
return get_args(Publisher[T])[0]
#This works
print(get_args(Publisher[int])[0])
#This doesn't
p = Publisher[int]("hello")
print(p.get_type())
在这个例子中p.get_type()
返回~T
而不是int
解决方案
显式传入类型,但将其注释为Type[T]
. T
这允许在不必指定它的情况下进行推断,使得只需指定一次类型(作为参数)就足够了。
class Publisher(Generic[T]):
# knowing `msg_type` defines `T`
def __init__(self, msg_type: Type[T], topic: str) -> None:
self._msg_type = msg_type
self._topic = topic
def publish(self, msg: T):
pass
def get_type(self) -> Type[T]:
return self._msg_type
# argument of `int` implies T = int
p = Publisher(int, "hello")
print(p.get_type()) # <class 'int'>
if TYPE_CHECKING:
reveal_type(p) # note: Revealed type is 'aaa_testbed.Publisher[builtins.int*]'
推荐阅读
- javascript - 修复字体 fabric.js 的光标
- parsing - LR(1) 解析,前瞻符号问题
- c - 矩阵结构 C
- swift - Xcode 11 和 Swift 5 中的 OAuth2 代码解析问题
- java - 将值传递给java中的成员变量
- r - 如何通过两个循环绘制图形
- swift - 标准输出 HackerRank Swift 没有响应
- ruby-on-rails - 有没有办法为 Activerecord 中的单个查询创建临时列?
- java - Calendar.getTime IllegalArgumentException
- debugging - 如何让用户将照片提交到网页上