如何注释采用可变长度元组的函数? (可变元组类型注释)

     2023-02-16     8

关键词:

【中文标题】如何注释采用可变长度元组的函数? (可变元组类型注释)【英文标题】:How to annotate function that takes a tuple of variable length? (variadic tuple type annotation) 【发布时间】:2019-07-11 20:03:18 【问题描述】:

我有一个函数,它接受一个不同长度的元组作为参数:

from typing import Tuple


def process_tuple(t: Tuple[str]):
    # Do nasty tuple stuff

process_tuple(("a",))
process_tuple(("a", "b"))
process_tuple(("a", "b", "c"))

当我像上面提到的那样注释函数时,我会收到这些错误消息

fool.py:9: error: Argument 1 to "process_tuple" has incompatible type "Tuple[str, str]"; expected "Tuple[str]"
fool.py:10: error: Argument 1 to "process_tuple" has incompatible type "Tuple[str, str, str]"; expected "Tuple[str]"

process_tuple 确实适用于元组,我将它们用作可变长度的不可变列表。我在网上没有找到关于这个话题的任何共识,所以我想知道我应该如何注释这种输入。

【问题讨论】:

您在运行代码时是否遇到这些错误?我运行代码没有任何错误。 我在运行 mypy 时遇到这些错误。 【参考方案1】:

我们可以像这样使用... 文字(又名Ellipsis)来注释可变长度的同构元组:

def process_tuple(t: Tuple[str, ...]):
    ...

之后,错误应该会消失。

来自docs:

要指定同构类型的变长元组,请使用字面量 省略号,例如Tuple[int, ...]。一个普通的Tuple 相当于 Tuple[Any, ...],然后转至tuple

【讨论】:

这实际上有点反直觉和反逻辑。如果我们假设List[str] 适用于可变长度列表,那么为什么Tuple[str] 不适用于可变长度元组?而(type(("a", "a")) == type(("a", "a", "a")) 产生True @Montreal:这是因为tuples 和lists 用于不同的目的:tuples 是异构容器(例如任意函数的位置参数或来自 RDBMS 的单个表记录,或在数学世界中——不同集合的笛卡尔积的元素(或笛卡尔积的联合),因此每个坐标可能有不同的类型,但它们的数量通常是固定的),而lists 是同质的(如集合相同的表记录或某些集合的有限元素序列) @Montreal: 所以Tuple[str] 是一个单一的str 对象tuple,而List[str] 是任意数量的str 对象的集合【参考方案2】:

除了 Azat 发布的省略号答案之外,您还可以使用 @typing.overloadtyping.Union 使其更明确

from typing import Tuple


@overload
def process_tuple(t: Tuple[str]):
    # Do nasty tuple stuff

@overload
def process_tuple(t: Tuple[str, str]):
    ...

或与联盟:

from typing import Tuple, Union


def process_tuple(t: Union[Tuple[str], Tuple[str, str], Tuple[str, str, str]]):
    # Do nasty tuple stuff

【讨论】:

我知道它,但我的元组可能很长,所以它不是一个选项。无论如何,谢谢。 btw overloads 应该在实施之前进行

python中列表和元组之间有啥区别?

...inenumber然后,可以将其用作字典中的键来存储有关位置的注释。另一方面,列表可用于存储多个位置。自然地,人们可能想在列表中添加或删除位置,因此使列表可变是有意义的。另一方面,从现有位置添加或删除项目没有意义... 查看详情

如何通过使用可变模板参数来专门化元组的类模板?

】如何通过使用可变模板参数来专门化元组的类模板?【英文标题】:Howtospecializeaclasstemplateforatuplebyusingvariadictemplatearguments?【发布时间】:2013-10-0303:02:19【问题描述】:如何为一个元组专门化一个类模板?我尝试以下但失败了... 查看详情

容器类型(代码片段)

...不能修改元组中的元素指的是如果当前元组中的元素为不可变对象则不能修改,如果是可变对象在不修改元素类型的情况下可以修改可变对象中的值。可变对象:list、dict、set不可变对象:tuple、string、int、float、bool元组的作用... 查看详情

深入理解python列表和元组

...小是固定的,无法增加、删除或者改变。列表是动态的、可变的,而元组是静态的、不可变的。列表的存储方式,如下所示:元组的存储方式,如下所示:存储同样的元素,元组使用的存储空间更小,要少16个字节。这是因为列... 查看详情

数据类型(代码片段)

...类型的值,元组是在()内定义值,与列表相比元组是不可变的(可以作为字典的key)age=(18,19,20,21)本质:age=tuple(18,19,20,21)具体操作(元组与列表操作相同)1、按照索引取值(正向取,反向取),因为元组是不可变类型,... 查看详情

python中,即使元组的成员对象中有列表,元组也是不可变的,是不是正确

Python中,即使元组的成员对象中有列表,元组也是不可变的,是否正确不完全正确。理由是,元组的“不可变”体现在内存地址的不可变,而元组中包含列表,尽管做到了元素地址不变,但列表作为元素,它的内容是可以变的。... 查看详情

python不可变对象元组(tuple)详解

...使用元组看似鸡肋的内置对象呢?我们可以通过元组的不可变性运用在一些场景中,因为其不可变性本身本身就提供了某种完整性,比如使用元组来实现函数的多返回值,作为参数传递给函数调用、或是从函数调用那里获得参数... 查看详情

python列表和元组的区别

...定义。元组通常用于使语句或用户定义的函数能够安全地采用一组值,也就是说,所使用的元组的值不会改变。元组可以嵌套。列表控件可以在四种不同的视图中显示项目。您可以将项目分组到有或没有列标题的列中,并显示附... 查看详情

元组的相对不可变性(代码片段)

...,等等)一样,保存的是对象的引用。如果引用的元素是可变的,即便元组本身不可变,元素依然可变。也就是说,元组的不可变性其实是指tuple数据结构的物理内容(即保存的引用)不可变,与引用的对象无关。t1=(1,2,[30,40])t2=... 查看详情

scala基础六scalamap和元组的操作

...是唯一的。Map也叫哈希表(Hashtables)。Map有两种类型,可变与不变,区别在于可变对象可以修改它,而不可变对象不可以。默认情况下Scala使用不可变Map。如果你需要使用可变集合,你需要显式的引入importscala.collection.mutable.Map... 查看详情

如何将元组扩展为可变参数模板函数的参数?

】如何将元组扩展为可变参数模板函数的参数?【英文标题】:HowdoIexpandatupleintovariadictemplatefunction\'sarguments?【发布时间】:2010-10-1519:23:27【问题描述】:考虑带有可变模板参数的模板化函数的情况:template<typenameTret,typename...T... 查看详情

复合数据类型,英文词频统计(代码片段)

1.列表,元组,字典,集合分别如何增删改查及遍历。#列表的遍历myList=["小红","小李",80,90]print("列表的遍历:")forl1inmyList:print(l1)#元组的遍历myTuple=(23,65,79,50)print("元组的遍历:")forT1inmyTuple:print(T1)#集合的遍历mySet=43,58,90,74print("集... 查看详情

day2基本类型和函数

列表,元组,字典的转换。list列表是一组可变的元素集合列表是‘[]‘括号组成的,[]括号包含所有元素,列表的创建可以传递字符串,也可以传递多个字符串来创建列表。如"asd",/"a","b"... tuple元组的创建和列表一致,区别在... 查看详情

python基础语法(代码片段)

目录1.注释的使用单行注释多行注释2.变量的使用变量定义变量的类型不同类型变量之间的计算变量的输入类型转换变量的格式化输出变量的命名3.判断语句if语句使用else语句使用elif语句使用if语句的嵌套使用4.运算符算数运算符... 查看详情

可变长参数(*,**)

可变长参数python还支持可变长度的参数列表。可变长参数可以是元组或者字典。1.元组当参数以*开头时,表示变长参数将被视为一个元组,格式如下:deffunc(*t):在func()函数中t被视为一个元组,使用t[index]获取每一个可变长参数。... 查看详情

数据类型-元组

...,只是它一旦创建,不能修改,所以叫只读列表。特性不可变元组本身不可变,如果元组中还包含其它可变元素,这些可变元素可以改变功能:indexcount 切片使用场景:1、显示的告知别人,此处数据不可修改。2、数据库连接... 查看详情

可变不可变数据类型和hash

一、可变和不可变数据类型  在python中,我们对数据类型除了分为数字类型、字符串类型、列表类型、元组类型、字典类型和集合类型外,还有另外一种分类方式,我们给数据类型分为可变数据类型和不可变数据类型。  可... 查看详情

好好学python·元组(代码片段)

...组的切片操作元组推导式生成器生成器是什么?语法如何使用操作生成器?数据类型详解-元组元组中的元素一但定义不可以修改,因此元组称为不可变数据类型元组定义定义空元组变量=(),或者变量=tuple()还可以... 查看详情