python中 ->符号的意思

What does -> mean in Python function definitions?

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

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

可选的"arrow"块在python 2中不存在,我在python 3中找不到任何关于其含义的信息。结果证明这是正确的python,并且被解释器接受:

1
2
def f(x) -> 123:
    return x

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

    百万千克1我不能在这里测试x,因为它还没有定义,百万千克1百万千克1不管我在箭头后面放什么(例如2 < 1),它都不会影响函数行为。百万千克1

习惯了这种句法的人能解释一下吗?


这是一个函数注释。

更详细地说,python 2.x有docstrings,它允许您将元数据字符串附加到各种类型的对象上。这非常方便,所以python 3通过允许您将元数据附加到描述其参数和返回值的函数来扩展特性。

没有预想到的用例,但是PEP提出了几个。一个非常方便的方法是允许您用期望的类型来注释参数;然后可以很容易地编写一个修饰器来验证注释或强制参数为正确的类型。另一种方法是允许特定于参数的文档,而不是将其编码为docstring。


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

实例:

1
2
3
4
5
>>> 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'}

注释是字典,因此可以执行以下操作:

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

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

1
2
3
4
5
6
7
8
9
>>> 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'

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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)

印刷品

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


如其他答案所述,->符号用作函数注释的一部分。不过,在更新版本的python >= 3.5中,它有一个定义的含义。

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

但是,在python 3.5中,pep 484—类型提示对此有一个单一的含义:->用于指示函数返回的类型。这似乎也将在未来版本中强制执行,如注释的现有用法所述:

The fastest conceivable scheme would introduce silent deprecation of non-type-hint annotations in 3.6, full deprecation in 3.7, and declare type hints as the only allowed use of annotations in Python 3.8.

(强调矿山)

据我所知,从3.6起,这实际上还没有实现,因此它可能会被转发到未来的版本。

根据这一点,您提供的示例:

1
2
def f(x) -> 123:
    return x

将来将被禁止(并且在当前版本中会令人困惑),需要将其更改为:

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

为了有效地描述函数f返回类型为int的对象。

python本身并没有以任何方式使用注释,它会填充并忽略它们。由第三方图书馆与之合作。


Python忽略了它。在以下代码中:

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

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

python还支持参数注释:

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

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

https://docs.python.org/3/reference/compound-stmts.html函数定义https://www.python.org/dev/peps/pep-3107/


def function(arg)->123:

它只是一个返回类型,在本例中,整数与您编写的数字无关。

和Java一样:

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

但是对于python(jim fasarakis hilliard是这样说的)返回类型,它只是一个提示,所以它建议返回,但无论如何允许返回其他类型,比如字符串。