Python Typing:创建一个具有泛型类型的类函数,并通过类访问该类型 [英] Python Typing : Create a class function with a generic type, and also access that type through the class
问题描述
我有一个可以发布某种类型消息的发布者:
T = TypeVar('T')类发布者(通用 [T]):def __init__(self, topic: str) ->没有任何:self.__topic = 主题def 发布(自我,味精:T):经过# 举个例子,创建一个可以发布整数的发布者p = Publisher[int](喋喋不休")p.publish(1)
这有效,并且发布函数具有正确的类型提示,但我希望能够使用 get_type()
函数访问发布者的类型.
一个简单的方法是将消息类型传递给构造函数:
T = TypeVar('T')类发布者(通用 [T]):def __init__(self, msg_type: type, topic: str) ->没有任何:self.__msg_type = msg_typeself.__topic = 主题def 发布(自我,味精:T):经过def get_type(self) ->类型:返回 self.__msg_typep = Publisher[int](int, chatter")p.publish(1)
但这需要在 p = Publisher[int](int, "chatter")
行中写两次 int
,这看起来有点笨拙和多余.>
我尝试将发布者的创建包装在一个函数中,这样您就不必两次编写 int
,但我遇到了一个问题:
T = TypeVar('T', bound=type)类发布者(通用 [T]):def __init__(self, msg_type: type, topic: str) ->没有任何:self.__msg_type = msg_typeself.__topic = 主题def 发布(自我,味精:T):经过def get_type(self) ->类型:返回 self.__msg_typedef create_publisher(msg_type: T, topic: str) ->出版商[T]:return Publisher[T](msg_type, topic)p = create_publisher(int, 你好")p.publish(1) #Fails 因为它期望 Type[int],而不是 int 的实例
所以我需要的是一种在 typehint 上下文中将 Type[x]
转换为 x
的方法.本质上与 Type
的作用相反.
例如,最后一个例子会变成:
T = TypeVar('T', bound=type)类发布者(通用 [T]):def __init__(self, msg_type: type, topic: str) ->没有任何:self.__msg_type = msg_typeself.__topic = 主题def 发布(自我,味精:InstanceOf[T]):经过def get_type(self) ->类型:返回 self.__msg_typedef create_publisher(msg_type: T, topic: str) ->出版商[T]:return Publisher[T](msg_type, topic)p = create_publisher(int, 你好")p.publish(1)
但我不知道如何使 InstanceOf
通用.
无论如何我可以做到这一点吗?或者任何其他方式来获得我想要的功能,而不必在 p = Publisher[int](int, "chatter")
int
>编辑
这是另一种也不起作用的尝试,但应该澄清我正在尝试做的事情:
T = TypeVar('T')类发布者(通用 [T]):def __init__(self, topic: str) ->没有任何:self.__topic = 主题def 发布(自我,味精:T):经过def get_type(self) ->类型:返回 get_args(Publisher[T])[0]#这有效打印(get_args(发布者[int])[0])#这不p = Publisher[int](你好")打印(p.get_type())
在这个例子中 p.get_type()
返回 ~T
而不是 int
显式传入类型,但将其注释为 Type[T]
.这允许推断 T
而无需指定它,从而足以仅指定一次类型(作为参数).
class Publisher(Generic[T]):# 知道 `msg_type` 定义了 `T`def __init__(self, msg_type: Type[T], topic: str) ->没有任何:self._msg_type = msg_typeself._topic = 主题def 发布(自我,味精:T):经过def get_type(self) ->类型[T]:返回 self._msg_type# `int` 的参数意味着 T = intp = Publisher(int, 你好")print(p.get_type()) # 如果 TYPE_CHECKING:reveal_type(p) # 注意:显示类型是 'aaa_testbed.Publisher[builtins.int*]'
I have a publisher that can publish messages of a certain type:
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)
This works, and the publish function has the correct type hint, but I want to be able to access the type of the publisher with a get_type()
function.
A simple way to do this is to pass the message type into the constructor:
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)
But this requires writing int
twice in the line p = Publisher[int](int, "chatter")
which seems a bit clumsy and redundant.
I tried wrapping the creation of the publisher in a function so that you don't have to write int
twice, but I get a problem:
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
So what I need, is a method to get convert Type[x]
into x
in a typehint context. Essentially the inverse of what Type
does.
e.g, the last example would become:
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)
But I do not know how to make the InstanceOf
generic.
Is there anyway I can do this? Or any other way to get the functionality I want without having to write int
twice in the line p = Publisher[int](int, "chatter")
edit
Here is another attempt that also doesn't work, but should clarify what I'm trying to do:
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())
In this example p.get_type()
returns ~T
instead of int
Pass in the type explicitly, but annotate it as Type[T]
. This allows inference of T
without having to specify it, making it enough to specify the type only once (as the argument).
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*]'
这篇关于Python Typing:创建一个具有泛型类型的类函数,并通过类访问该类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!