首页 > 编程问答 >Python - 如何使用存储在类变量中的类型作为同一类方法的参数的类型提示?

Python - 如何使用存储在类变量中的类型作为同一类方法的参数的类型提示?

时间:2024-07-25 16:53:30浏览次数:11  
标签:python python-typing

考虑下面的代码:

from typing import Protocol, ClassVar, Any


class Tool(Protocol):
    t: ClassVar

    # def f(self, params: self.t) -> Any:
    # NameError: name 'self' is not defined
    def f(self, params) -> Any:
        pass


class Sum:
    t: ClassVar = list[int]

    def f(self, params: list[int]) -> int:
        return sum(params)


def use_tool(tool: Tool, params: Any) -> Any:
    return tool.f(params)


s = Sum()
print(use_tool(s, [1, 2]))

我想定义一个协议 Tool ,这样像 Sum 这样的类可以用特定的 t 来实现​​它,而在 Sum.f() 等方法中, params 会受到限制在类型检查中具有 t 的类型,它存储类型/类对象。我该怎么做?

我试图在类型注释中使用 self.t 来引用 t ,但这不起作用,用 self 替换 typing.Self 也不起作用。

我认为存储类型对于 f() 的参数在假设 t 存储 a pydantic.BaseModel (这意味着 t 的类型为 ModelMetaclass )的情况下很有用,那么在像 use_tool 这样的函数中,我可以查看 t via t.model_dump_json() 的模式。此外, use_tool() 可以将 JSON 字符串作为输入,并在调用 t.model_validate_json() 之前通过 Tool.f 将其解析为适当的模型。


你可以使用 TypeVar 和泛型来实现你想要的。 以下是如何操作:

from typing import Protocol, TypeVar, Generic, Any

T = TypeVar('T')

class Tool(Protocol, Generic[T]):
    t: type[T]

    def f(self, params: T) -> Any:
        ...


class Sum:
    t = list[int]

    def f(self, params: list[int]) -> int:
        return sum(params)


def use_tool(tool: Tool[Any], params: Any) -> Any:
    return tool.f(params)


s = Sum()
print(use_tool(s, [1, 2]))

解释:

  1. TypeVar : 我们首先定义一个 TypeVar T ,它表示一个可以是任何类型的占位符。
  2. Generic[T] : 我们使 Tool 协议成为一个泛型协议,它接受一个类型参数 T 。这意味着 Tool 可以被任何具体的类型实例化,例如 Tool[list[int]] Tool[str]
  3. t: type[T] : 我们将 t 声明为一个类变量,其类型为 type[T] 。这表示 t 将存储一个类型,而该类型必须是 T 的子类。
  4. f(self, params: T) -> Any : 在 f 方法中,我们使用 T 作为 params 参数的类型提示。 这意味着传递给 f 的参数类型必须与 t 存储的类型匹配。

通过这种方式,你可以确保传递给 f 方法的参数类型与存储在 t 中的类型一致,同时仍然允许不同的类以不同的类型实现 Tool 协议。

标签:python,python-typing
From: 78792255

相关文章

  • 从Python列表中提取值
    代码图片我只想从.dat文件中提取单个值,到目前为止,我已经成功提取了我想要的值,但我将各个字符串添加在一起。它非常笨重,所以寻找一种更平滑的方法,它只会给我行中的第一个值(-300)。谢谢代码:current_dir=os.getcwd()work_dir="\workDir"......
  • 如何从另一个 python 文件运行一个 python 文件
    我正在尝试从另一个python运行一个python文件,但是当涉及到调用另一个python文件中的方法时,它只会重新运行当前的python文件。我尝试了这段代码。我将导入放入log_user_in方法中,因为如果我将其导入到文件顶部,则会出现循环导入错误。这是我的代码片段fromtkinter......
  • 如何在Mac电脑上安装Python 2
    Python是一种高级编程语言,广泛应用于数据科学、网络开发、人工智能等领域。本文将介绍如何在Mac电脑上安装Python2,帮助初学者快速入门。一、下载Python2安装包在Python官网上下载Python2的安装包,网址为https://www.python.org/downloads/release/python-2718/ 。下载完......
  • 我的 python 抓取数据是空的,不确定我的代码出了什么问题
    我的结果是空的,不确定我的代码出了什么问题:这里是我的代码:#尝试从该网站获取数据https://www.watsons.com.sg/health/c/2100000?currentPage=1importrequestsfrombs4importBeautifulSoupimportpandasaspd#Settingdisplayoptionsforpandaspd.......
  • Chrome 浏览器更新后,我的 python tagui 代码工作不稳定。问题的解决方法是什么
    我编写了一个pythontagui脚本来在chrome中操作Intranet网页。它运行良好。但是在chrome浏览器更新后,脚本每次都会在某个时刻随机停止,并且也不会抛出错误。请帮忙。我尝试重新启动电脑,但这并没有解决问题。Chrome浏览器更新后,TagUI脚本工作不稳定的问题可能由以......
  • 如何从另一个文件运行 python 文件
    我正在尝试从另一个名为LoginOrReg的文件运行一个名为HabitTracker的python文件,但是当我这样做时,它会重新运行LoginOrReg文件。我已经尝试过这个classLoginOrReg:def__init__(self,db,cursor,login_username,data):self.db=mysql.connector.......
  • Python的字典和集合
    一、字典1.定义字典字典和列表虽然类似,但是字典是无序的可变序列,并且可以像查字典一样去查找。字典的元素都是成对出现的,每个元素都是由冒号“:”和键值对(“:”左边的称为键或者Key,“:”右边的称为值或者Value)构成的,用“{}”标识,元素之间用逗号“‘,”分隔。字典的键必须是唯一......
  • 在Python中字典是如何通过哈希表实现的以及哈希冲突是如何解决的
    哈希表(散列表)的工作原理哈希表是一种使用哈希函数组织数据,以支持快速插入和搜索的数据结构。它通过哈希函数将输入的键(key)映射到表中的一个位置(即索引或槽位),从而以接近常数时间复杂度进行查找、插入和删除操作。哈希表的基本工作流程如下:哈希函数:哈希函数接受一个输入(键),并......
  • python cobs协议编解码算法demo
    1.SummaryCOBS(ConsistentOverheadByteStuffing)是一种算法,直译为一致的开销字节填充。简而言之,无论数据包的内容如何,都能通过产生高效可靠明确的数据包帧,从而使接受端能够从损坏的包中恢复。通常使用0x00来作为数据包的分隔符,即切割数据包的片分隔符。当使用0x00作为......
  • 如何将unicode编码为字节,以便可以检索到原始字符串?在Python 3.11中
    在python3.11中,我们可以对字符串进行编码,如:string.encode('ascii','backslashreplace')这对于说:hellö=>hell\\xf6但是当我插入时hellöw\\xf6rldIgethell\\xf6w\\xf6rld(注意第二个有一个看起来像字符转义序列的文字部分)......