【发布时间】:2020-12-12 14:21:11
【问题描述】:
我有一个可以发布某种类型消息的发布者:
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)
但这需要在p = Publisher[int](int, "chatter") 行中写两次int,这似乎有点笨拙和多余。
我尝试将发布者的创建包装在一个函数中,这样您就不必写两次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 通用。
无论如何我可以做到这一点吗?或任何其他方式来获得我想要的功能,而无需在p = Publisher[int](int, "chatter") 行中写两次int
编辑
这是另一个不起作用的尝试,但应该澄清我正在尝试做的事情:
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
【问题讨论】:
-
您能否解释一下为什么需要
[int]部分。这似乎是多余的,没有它就可以编写代码。 -
@venky__ 我不确定我是否理解。
int只是一个例子。可以使用任何类型创建发布者。这能回答你的问题吗? -
不,我的意思是
Publisher[int](int, "chatter")可以写成Publisher (int, "chatter")。如果没有那为什么? -
@venky__ 我想在运行前使用
mypy捕获类型错误。Publisher[int]的[int]确保从现在开始,这个发布者publish函数只能用整数调用。如果没有这个,我将不得不在发布函数中进行 runtme 检查,以检查它是否以正确的类型被调用。
标签: python-3.x type-hinting python-typing