Python 函数定义中的 -> 是什么意思?

2024-12-12 08:41:00
admin
原创
142
摘要:问题描述:最近,在查看Python 3.3 语法规范时,我注意到了一些有趣的事情:funcdef: 'def' NAME parameters ['->' test] ':' suite Python 2 中没有可选的“箭头”块,我找不到有关其在 Python 3 中含义的任何信息。事实证明这是正确的 ...

问题描述:

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

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

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

def f(x) -> 123:
    return x

我认为这可能是某种先决条件语法,但是:

  • 我无法x在这里测试,因为它仍然未定义,

  • 无论我在箭头后放什么(例如2 < 1),它都不会影响函数行为。

熟悉这种语法风格的人可以解释一下吗?


解决方案 1:

它是一个函数注释。

更详细地说,Python 2.x 具有文档字符串,它允许您将元数据字符串附加到各种类型的对象。这非常方便,因此 Python 3 扩展了该功能,允许您将元数据附加到描述其参数和返回值的函数。

没有预先设想的用例,但 PEP 提出了几个。一个非常方便的用例是允许您使用预期类型注释参数;然后可以轻松编写一个装饰器来验证注释或将参数强制转换为正确的类型。另一个是允许特定于参数的文档,而不是将其编码到文档字符串中。

解决方案 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'}

注释是字典,因此您可以这样做:

>>> '{:,} {}'.format(kinetic_energy(12,30),
      kinetic_energy.__annotations__['return'])
'5,400.0 Joules'

您还可以拥有一个 Python 数据结构,而不仅仅是一个字符串:

rd={'type':float,'units':'Joules',
    'docstring':'Given mass and velocity returns kinetic energy in Joules'}
def f()->rd:
    pass

>>> f.__annotations__['return']['type']
<class 'float'>
>>> f.__annotations__['return']['units']
'Joules'
>>> f.__annotations__['return']['docstring']
'Given mass and velocity returns kinetic energy in Joules'

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

def validate(func, locals):
    for var, test in func.__annotations__.items():
        value = locals[var]
        try: 
            pr=test.__name__+': '+test.__docstring__
        except AttributeError:
            pr=test.__name__   
        msg = '{}=={}; Test: {}'.format(var, value, pr)
        assert test(value), msg

def between(lo, hi):
    def _between(x):
            return lo <= x <= hi
    _between.__docstring__='must be between {} and {}'.format(lo,hi)       
    return _between

def f(x: between(3,10), y:lambda _y: isinstance(_y,int)):
    validate(f, locals())
    print(x,y)

印刷

>>> f(2,2) 
AssertionError: x==2; Test: _between: must be between 3 and 10
>>> f(3,2.1)
AssertionError: y==2.1; Test: <lambda>

解决方案 3:

在下面的代码中:

def f(x) -> int:
    return int(x)

只是-> int告诉f()返回一个整数(但它不强制函数返回整数)。它被称为返回注释,可以作为访问f.__annotations__['return']

Python还支持参数注释:

def f(x: float) -> int:
    return int(x)

: float告诉阅读程序的人(以及一些第三方库/程序,例如 pylint)x应该是float。它作为 访问f.__annotations__['x'],本身没有任何意义。有关更多信息,请参阅文档:

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

解决方案 4:

正如其他答案所述,该->符号用作函数注释的一部分。>= 3.5但在较新版本的 Python 中,它具有明确的含义。

PEP 3107——函数注释描述了规范,定义了语法变化、它们的存储存在func.__annotations__以及它的用例仍然开放的事实。

3.5不过,在 Python 中, PEP 484 -- 类型提示赋予了它单一的含义:->用于指示函数返回的类型。这似乎也将在未来版本中得到强制执行,如现有的注释用途中所述:

最快的可想象方案是在 3.6 中引入非类型提示注释的静默弃用,在 3.7 中完全弃用,并将类型提示声明为 Python 3.8 中唯一允许使用的注释。

(重点是我的)

3.6据我所知,这实际上尚未实现,因此它可能会被推迟到未来的版本。

据此,您提供的示例:

def f(x) -> 123:
    return x

将来会被禁止(并且在当前版本中会造成混淆),需要将其更改为:

def f(x) -> int:
    return x

以便有效地描述该函数f返回一个类型对象int

Python 本身不会以任何方式使用注释,它基本上会填充并忽略它们。这取决于第三方库如何使用它们。

解决方案 5:

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

它在面向 Python 3.x 的现代库中广泛存在。

例如,在pandas-profiling库的代码中有很多地方都有这个功能,例如:

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.

解决方案 6:

def f(x) -> 123:
    return x

我的总结:

  1. Simply->的引入是为了让开发人员可以随意指定函数的返回类型。请参阅Python 增强提案 3107

  2. 这表明,随着 Python 被广泛采用,未来事态可能会如何发展——朝着强类型的方向发展——这是我个人的观察。

  3. 您还可以指定参数的类型。指定函数和参数的返回类型将有助于减少逻辑错误并提高代码的增强功能。

  4. 您可以将表达式作为返回类型(在函数和参数级别),并且可以通过注释对象的“return”属性访问表达式的结果。对于 lambda 内联函数,表达式/返回值的注释将为空。

解决方案 7:

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

print(f(45))

将给出结果:49

或者换句话说 '-> str' 对返回类型没有影响:

print(f(45).__class__)

<class 'int'>

解决方案 8:

def function(arg)->123:

它只是一种返回类型,在这种情况下整数并不重要,你写哪个数字。

比如Java

public int function(int args){...}

但是对于 Python(Jim Fasarakis Hilliard 的说法)来说, 返回类型只是一个提示,所以它建议返回但无论如何允许返回其他类型,如字符串。

解决方案 9:

->是在 python3 中引入的。

简单来说, ->后面的内容表示函数的返回类型。返回类型是可选的。

解决方案 10:

它只是告诉用户它期望什么或返回什么值

funcname.__annotations__将打印详细信息

喜欢

def function(name:str ,age:int) -> "printing the personal details ":
    print(f"name is {name} age is {age}")

function("test",20)
print(function.__annotations__)

输出

name is test age is 20
{'name': <class 'str'>, 'age': <class 'int'>, 'return': 'printing the personal details '}

即使您返回这些值,它也不会显示任何内容。

解决方案 11:

请参阅PEP3107规范。这些是函数注释。Python 2.x 有文档字符串。同样,Python 3 引入了 -> 作为函数注释的使用。Python 在生成文档时使用这些。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用