我最近在查看Python 3.3语法规范时注意到了一些有趣的事情:

funcdef: 'def' NAME parameters ['->' test] ':' suite


Python 2中缺少可选的“箭头”块,我找不到任何有关它在Python 3中含义的信息。事实证明这是正确的Python,并已被解释器接受:语法,但是:


我无法在此处测试x,因为它仍然是未定义的,
无论我在箭头后面加上什么(例如2 < 1),它都不会影响函数行为。

习惯此语法的人可以解释它吗?

#1 楼

这是一个函数注释。

更详细地讲,Python 2.x具有文档字符串,可用于将元数据字符串附加到各种类型的对象。这非常方便,因此Python 3通过允许您将元数据附加到描述其参数和返回值的函数中来扩展了该功能。一种非常方便的方法是允许您使用期望的类型注释参数。这样就很容易编写一个装饰器来验证注释或将参数强制为正确的类型。另一个是允许使用特定于参数的文档,而不是将其编码为文档字符串。

评论


该信息可作为.__ annotations__属性使用。

–马丁·彼得斯(Martijn Pieters)♦
2013年1月17日13:06

哇,我错过了相当广泛的知识-不仅返回值注释,而且参数注释。非常感谢你 :)。

–克罗顿
2013年1月17日13:16

@Krotton不能怪您错过它,它实际上没有使用。我只见过使用它们的单个库,这很晦涩。

–user395760
2013年1月17日13:19



__annotations__属性是一个字典。键返回是用于检索箭头后面的值的键。

–基思
13年1月17日在13:20

@delnan-大部分未使用的原因可能是因为大多数python库仍旨在与python2.x兼容。随着python3.x开始变得越来越标准,我们可能会在这里和那里看到更多的东西……

–mgilson
2013年1月17日14:15

#2 楼

这些是PEP 3107中涵盖的功能注释。具体来说,->标记了返回功能注释。

示例:因此您可以执行以下操作:

>>> def kinetic_energy(m:'in KG', v:'in M/S')->'Joules': 
...    return 1/2*m*v**2
... 
>>> kinetic_energy.__annotations__
{'return': 'Joules', 'v': 'in M/S', 'm': 'in KG'}


您还可以使用python数据结构,而不仅仅是字符串:

>>> '{:,} {}'.format(kinetic_energy(20,3000),
      kinetic_energy.__annotations__['return'])
'90,000,000.0 Joules'


或者,您可以使用函数属性来验证被调用的值:


评论


我认为这是一个完整的例子。

–德什瓦尔
8月19日的1:17

#3 楼

在以下代码中:
def f(x) -> int:
    return int(x)
-> int只是告诉f()返回一个整数(但并不强制该函数返回整数)。它称为返回注释,可以作为f.__annotations__['return']进行访问。

Python也支持参数注释:该程序(和某些第三方库/程序,例如pylint)认为: float应该是x。它以float的形式访问,并且本身没有任何意义。请参阅文档以获取更多信息:

https://docs.python.org/3/reference/compound_stmts.html#function-definitions
https://www.python.org/ dev / peps / pep-3107 /

#4 楼

如其他答案所述,->符号用作功能注释的一部分。不过,在最新版本的Python >= 3.5中,它具有定义的含义。

PEP 3107-功能注释描述了规范,定义了语法更改,存储了它们的func.__annotations__的存在以及用例的事实仍然是开放的。

但是在Python 3.5中,PEP 484-类型提示对此具有唯一含义:->用于指示函数返回的类型。似乎还将在将来的版本中强制执行此操作,如注释的现有用法如何:


最快的可能方案将在3.6中引入对非类型提示注释的无提示弃用,在3.7中完全弃用,并声明类型提示为Python 3.8中唯一允许使用注释的方法。据我所知,它实际上是从3.6开始实现的,因此它可能会与将来的版本冲突。

根据此,您提供的示例: />
将来会被禁止(并且在当前版本中会造成混淆),因此需要将其更改为:
有效地描述了函数f返回了类型为int的对象。

Python本身不以任何方式使用批注,它几乎填充并忽略了它们。取决于第三方库。

评论


好答案。出于好奇,您是否在代码中使用它们?

–PatrickT
6月18日在3:24



#5 楼

def function(arg)->123:

它只是一个返回类型,在这种情况下,整数与所写的数字无关紧要。

像Java一样: />
但是对于Python(Jim Fasarakis Hilliard所说的话)来说,返回类型只是一个提示,因此建议返回,但无论如何都可以返回其他类型,例如字符串。.

#6 楼

这意味着函数返回的结果类型,但是可以是None

在面向Python 3.x的现代库中很普遍。

例如例如在许多地方的库pandas配置文件代码中:

def get_description(self) -> dict:

def get_rejected_variables(self, threshold: float = 0.9) -> list:

def to_file(self, output_file: Path or str, silent: bool = True) -> None:
"""Write the report to a file.


评论


“这意味着函数返回的结果类型,但是可以为None。”它可以是None或任何其他类型。

– Ebram Shehata
5月13日5:05



#7 楼

def f(x) -> 123:
    return x


我的摘要:


简单地引入了->是为了使开发人员可以选择指定函数的返回类型。请参阅Python增强建议3107
,这表明随着Python的广泛使用,事情将来会如何发展-指示强类型化-这是我个人的观察。
也可以为参数指定类型。指定函数和参数的返回类型将有助于减少逻辑错误并改进代码增强。
您可以将表达式作为返回类型(对于函数和参数级别),并且可以通过注释访问表达式的结果对象的“返回”属性。对于lambda内联函数的表达式/返回值,注释将为空。


#8 楼

def f(x) -> str:
return x+4

print(f(45))

# will give the result : 
49

# or with other words '-> str' has NO effect to return type:

print(f(45).__class__)

<class 'int'>