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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14379753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:14:38  来源:igfitidea点击:

What does -> mean in Python function definitions?

pythonpython-3.xannotationsfunction-definition

提问by Krotton

I've recently noticed something interesting when looking at Python 3.3 grammar specification:

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

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

The optional 'arrow' block was absent in Python 2 and I couldn't find any information regarding its meaning in Python 3. It turns out this is correct Python and it's accepted by the interpreter:

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

def f(x) -> 123:
    return x

I thought that this might be some kind of a precondition syntax, but:

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

  • I cannot test xhere, at it is still undefined,
  • No matter what I put after the arrow (e.g. 2 < 1), it doesn't affect the function behaviour.
  • 我无法x在这里测试,因为它仍然未定义,
  • 无论我在箭头后面放什么(例如2 < 1),它都不会影响函数行为。

Could anyone accustomed with this syntax explain it?

任何习惯于这种语法的人都可以解释一下吗?

采纳答案by Katriel

It's a function annotation.

这是一个函数注解

In more detail, Python 2.x has docstrings, which allow you to attach a metadata string to various types of object. This is amazingly handy, so Python 3 extends the feature by allowing you to attach metadata to functions describing their parameters and return values.

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

There's no preconceived use case, but the PEP suggests several. One very handy one is to allow you to annotate parameters with their expected types; it would then be easy to write a decorator that verifies the annotations or coerces the arguments to the right type. Another is to allow parameter-specific documentation instead of encoding it into the docstring.

没有先入为主的用例,但 PEP 建议了几个。一个非常方便的方法是允许您使用预期类型来注释参数;然后很容易编写一个装饰器来验证注释或将参数强制为正确的类型。另一个是允许特定于参数的文档而不是将其编码到文档字符串中。

回答by dawg

These are function annotations covered in PEP 3107. Specifically, the ->marks the return function annotation.

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

Examples:

例子:

>>> 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'}

Annotations are dictionaries, so you can do this:

注释是字典,所以你可以这样做:

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

You can also have a python data structure rather than just a string:

您还可以拥有一个 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'

Or, you can use function attributes to validate called values:

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

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)

Prints

印刷

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

回答by Dimitris Fasarakis Hilliard

As other answers have stated, the ->symbol is used as part of function annotations. In more recent versions of Python >= 3.5, though, it has a definedmeaning.

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

PEP 3107 -- Function Annotationsdescribed the specification, defining the grammar changes, the existence of func.__annotations__in which they are stored and, the fact that it's use case is still open.

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

In Python 3.5though, PEP 484 -- Type Hintsattaches a single meaning to this: ->is used to indicate the type that the function returns. It also seems like this will be enforced in future versions as described in What about existing uses of annotations:

但是在 Python 中3.5PEP 484 -- Type Hints附加了一个单一的含义:->用于指示函数返回的类型。这似乎也将在未来版本中强制执行,如关于注释的现有用途中所述

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 中引入对非类型提示注释的静默弃用,在 3.7 中完全弃用,并将类型提示声明为 Python 3.8 中唯一允许使用的注释。

(Emphasis mine)

(强调我的)

This hasn't been actually implemented as of 3.6as far as I can tell so it might get bumped to future versions.

3.6据我所知,这还没有真正实现,所以它可能会被撞到未来的版本中。

According to this, the example you've supplied:

据此,您提供的示例:

def f(x) -> 123:
    return x

will be forbidden in the future (and in current versions will be confusing), it would need to be changed to:

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

def f(x) -> int:
    return x

for it to effectively describe that function freturns an object of type int.

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

The annotations are not used in any way by Python itself, it pretty much populates and ignores them. It's up to 3rd party libraries to work with them.

Python 本身不会以任何方式使用注释,它几乎填充并忽略它们。由 3rd 方图书馆与他们合作。

回答by Mike D3ViD Tyson

def function(arg)->123:

def function(arg)->123:

It's simply a return type, integerin this case doesn't matter which number you write.

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

like Java:

Java

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

But for Python (how Jim Fasarakis Hilliardsaid) the return type it's just an hint, so it's suggest the return but allow anyway to return other type like a string..

但是对于 Python(Jim Fasarakis Hilliard怎么说) ,返回类型只是一个提示,因此建议返回但无论如何允许返回其他类型,如字符串..

回答by MaxiMouse

In the following code:

在以下代码中:

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

the -> intjust tells that f()returns an integer (but it doesn't force the function to return an integer). It is called a return annotation, and can be accessed as f.__annotations__['return'].

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

Python also supports parameter annotations:

Python 还支持参数注解:

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

: floattells people who read the program (and some third-party libraries/programs, e. g. pylint) that xshould be a float. Itis accessed as f.__annotations__['x'], and doesn't have any meaning by itself. See the documentation for more information:

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

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

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

回答by Vitalii

This means the type of result the function returns, but it can be None.

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

It is widespread in modern libraries oriented on Python 3.x.

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

For example, it there is in code of library pandas-profilingin many places for example:

例如,它在很多地方的库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.

回答by maz

def f(x) -> 123: return x

def f(x) -> 123: 返回 x

My summary:

我的总结:

  1. Simply -> is introduced to get developers optionally specify the return type of the function. See Python Enhancement Proposal 3107

  2. This is an indication of how things may develop in future as Python is adopted extensively - an indication towards strong typing - this is my personal observation.

  3. You can specify types for arguments as well. Specifying return type of the functions and arguments will help in reducing logical errors and improving code enhancements.

  4. You can have expressions as return type (for both at function and parameter level) and the result of the expressions can be accessed via annotationsobject's 'return' attribute. annotationswill be empty for the expression/return value for lambda inline functions.

  1. 简单地 -> 被引入以让开发人员选择性地指定函数的返回类型。参见 Python 增强提案 3107

  2. 这表明随着 Python 的广泛采用,未来可能会如何发展——这是对强类型的一种暗示——这是我个人的观察。

  3. 您也可以为参数指定类型。指定函数和参数的返回类型将有助于减少逻辑错误和改进代码增强。

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