Python 3.x Python类型:使用泛型类型创建类函数,并通过类访问该类型
我有一个发布者,可以发布特定类型的邮件:Python 3.x Python类型:使用泛型类型创建类函数,并通过类访问该类型,python-3.x,typing,python-typing,Python 3.x,Typing,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
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)
这是可行的,publish函数具有正确的类型提示,但我希望能够使用get\u 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
所以我需要的是一个方法,在typehint上下文中将Type[x]
转换为x
。本质上与类型的功能相反
e、 g,最后一个例子是:
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)
但是我不知道如何使
的实例通用
还有什么我可以做的吗?或者以任何其他方式获得我想要的功能,而不必在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
我有一个基于的答案,但它取决于未记录的实现细节
from typing import TypeVar, Generic, get_args, get_origin
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(self.__orig_class__)[0]
p = Publisher[int]("hello")
print(p.get_type())
显式传入类型,但将其注释为type[T]
。这允许在不必指定的情况下推断T
,使其足以只指定一次类型(作为参数)
类发布器(通用[T]):
#知道“msg_type”定义了“T”`
定义初始化(self,消息类型:type[T],主题:str)->None:
self.\u msg\u type=msg\u type
self.\u topic=主题
def发布(self,msg:T):
通过
def get_类型(自身)->类型[T]:
返回self.\u msg\u类型
#'int'的参数意味着T=int
p=发布者(int,“hello”)
打印(p.get_type())#
如果类型_检查:
显示类型(p)#注意:显示类型为“aaa_testbed.Publisher[builtins.int*]”
您能解释一下为什么需要[int]
零件吗。这似乎是多余的,没有它就无法编写代码。@venky_uuu我不确定我是否理解。int
就是一个例子。可以使用任何类型创建发布服务器。这回答了你的问题吗?不,我的意思是Publisher[int](int,“chatter”)
可以写成Publisher(int,“chatter”)
。如果没有,那么为什么?@venky\uuuu。我想在运行前使用mypy
捕捉类型错误。Publisher[int]
的[int]
确保从现在起,只能使用int调用Publisherpublish
函数。如果没有此功能,我将不得不在publish函数中执行runtme检查,以检查是否使用正确的类型调用了它。相关: