Python Typing:创建一个具有泛型类型的类函数,并通过类访问该类型 [英] Python Typing : Create a class function with a generic type, and also access that type through the class

查看:22
本文介绍了Python Typing:创建一个具有泛型类型的类函数,并通过类访问该类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可以发布某种类型消息的发布者:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆