首页 > 编程问答 >如何注释类对象(而不是类实例)的类型?

如何注释类对象(而不是类实例)的类型?

时间:2024-07-30 12:46:16浏览次数:7  
标签:python python-typing

注释需要类对象而不是该类实例的函数参数的正确方法是什么?

在下面的示例中, some_class 参数预计是类型实例(这是一个类),但是这里的问题是 type 太宽泛:

def construct(some_class: type, related_data:Dict[str, Any]) -> Any:
    ...

some_class 需要一组特定类型对象的情况下,使用 type 根本没有帮助。 typing 模块可能需要一个类泛型来执行此操作:

def construct(some_class: Class[Union[Foo, Bar, Baz]], related_data:Dict[str, Any]) -> Union[Foo, Bar, Baz]:
    ...

在上面的示例中, some_class Foo Bar Faz 类,而不是它的实例。它们在类树中的位置并不重要,因为 some_class: Class[Foo] 也应该是有效的情况。因此,

# classes are callable, so it is OK
inst = some_class(**related_data)

# instances does not have __name__
clsname = some_class.__name__

# an operation that only Foo, Bar and Baz can perform.
some_class.a_common_classmethod()

对于 mypy、pytype、PyCharm 等应该没问题。

当前的实现(Python 3.6 或更早版本)如何做到这一点?


是对的, typing.Type 太宽泛,无法指定一组特定的类。在 Python 3.7 及更高版本中,可以使用 typing.Type 附带的方括号语法来实现想要的:

from typing import Type, Dict, Any, Union

class Foo:
    ...

class Bar:
    ...

class Baz:
    ...

def construct(some_class: Type[Union[Foo, Bar, Baz]], related_data: Dict[str, Any]) -> Union[Foo, Bar, Baz]:
    return some_class(**related_data)

# 正确使用
construct(Foo, {})
construct(Bar, {})
construct(Baz, {})

# 错误使用 - 会被类型检查器标记
construct(int, {})

在这种情况下, Type[Union[Foo, Bar, Baz]] 表示 some_class 参数必须是 Foo Bar Baz 类的类型对象。

对于 Python 3.6 或更早版本,没有直接的方法来实现这种类型提示。可以使用字符串字面量来近似表示:

def construct(some_class: 'Type[Union[Foo, Bar, Baz]]', related_data: Dict[str, Any]) -> Union[Foo, Bar, Baz]:
    return some_class(**related_data)

但这不会提供运行时类型检查。

另一种选择是使用类型注释工具(例如 MyPy)提供的 typing_extensions 包中的 Protocol 来定义一个协议,指定所需的类方法或属性:

from typing import Protocol, Dict, Any

class MyProtocol(Protocol):
    def a_common_classmethod(self) -> None:
        ...

def construct(some_class: Type[MyProtocol], related_data: Dict[str, Any]) -> Any:
    some_class.a_common_classmethod()
    ...

这种方法允许根据行为而不是具体的类来约束类型。

总而言之,使用 typing.Type 和方括号语法是在 Python 3.7 及更高版本中注释类对象类型注释的首选方法。对于旧版本,可以使用字符串字面量或 Protocol 来实现类似的结果。

标签:python,python-typing
From: 41417679

相关文章

  • 从零开始的Python开发日记(7):短信验证功能开发流程
    短信验证功能开发流程在开发一个包含登录、注册以及短信验证的功能时,你需要遵循一个系统的开发流程。以下是实现这一功能的基本步骤,包括所需的技术和代码示例。1.环境配置首先,确保你的开发环境已经配置好,并安装了必要的库和工具。pipinstallfastapiuvicornsqlalche......
  • 【Python数值分析】革命:引领【数学建模】新时代的插值与拟合前沿技术
    目录​编辑第一部分:插值的基本原理及应用1.插值的基本原理1.1插值多项式1.2拉格朗日插值 1.3牛顿插值 1.4样条插值2.插值的Python实现2.1使用NumPy进行插值2.2使用SciPy进行插值2.2.1一维插值​编辑2.2.2二维插值3.插值的应用场景3.1数据平......
  • 在家用电脑上设置 Python 和 Jupyter,尝试打开 Jupyter 笔记本并显示错误,无法获取
    我有最新的Python版本3.12.4和以下版本的Jupyter:SelectedJupytercorepackages...IPython:8.26.0ipykernel:6.29.5ipywidgets:notinstalledjupyter_client:8.6.2jupyter_core:5.7.2jupyter_server:2.14.2jupyterlab......
  • Python - Reloading a module
    Eachmoduleisloadedintomemoryonlyonceduringaninterpretersessionorduringaprogramrun,regardlessofthenumberoftimesitisimportedintoaprogram.Ifmultipleimportsoccur,themodule’scodewillnotbeexecutedagainandagain.Suppose......
  • vscode python 3.7 pylance debugpy 插件 vsix
    可能报错  crashed5timesinthelast3minutes.Theserverwillnotberestarted.  ---pylance 可能报错  cannotreadpropertiesofundefinedreadingresolveEnvironment   --- debugger可能      vscodepython3.7调试没有反应......
  • Python获取秒级时间戳与毫秒级时间戳的方法[通俗易懂]
    参考资料:https://cloud.tencent.com/developer/article/21581481、获取秒级时间戳与毫秒级时间戳、微秒级时间戳代码语言:javascript复制importtimeimportdatetimet=time.time()print(t)#原始时间数据print(int(t))......
  • CEFPython
    在Tkinter界面中直接嵌入Selenium的浏览器视图并不是一件直接的事情,因为Selenium本身并不提供图形界面嵌入的功能。Selenium主要用于自动化web浏览器,但它并不直接控制浏览器窗口的显示方式,而是依赖于WebDriver来与浏览器交互。然而,你可以使用一些替代方案来在Tkinter应用中模拟或......
  • 《最新出炉》系列初窥篇-Python+Playwright自动化测试-58 - 文件下载
    1.简介前边几篇文章讲解完如何上传文件,既然有上传,那么就可能会有下载文件。因此宏哥就接着讲解和分享一下:自动化测试下载文件。可能有的小伙伴或者童鞋们会觉得这不是很简单吗,还用你介绍和讲解啊,不说就是访问到下载页面,然后定位到要下载的文件的下载按钮后,点击按钮就可以了。其实......
  • Python - Function Annotations
     deffunc(s:str,i:int,j:int)->str:returns[i:j]Theparametersissupposedtobeastring,soweplaceacolonaftertheparameternameandthenwritestr.Parametersiandjaresupposedtobeintegerssowewriteintforthem.Returntypeis......
  • 使用带有 pythonKit XCODE 的嵌入式 Python,在 iOS 应用程序中与 OpenCV-python 签名不
    我根据Beewares使用指南在XCODE中将Python嵌入到我的iOS项目中https://github.com/beeware/Python-Apple-support/blob/main/USAGE.md运行时,我得到pythonKit找不到由ultralytics导入的cv2错误。当我将OpenCV-python添加到我的app_packages文件夹时......