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

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

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

def f(x) -> 123:
    return x

我认为这可能是一种前提语法,但是:

我不能在这里测试x,因为它仍然没有定义, 无论我在箭头后面放什么(例如2 < 1),它都不会影响函数的行为。

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


当前回答

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

funcname。__annotations__将打印细节

like

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

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

其他回答

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

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

但在Python 3.5中,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本身并不以任何方式使用注释,它基本上填充并忽略它们。这取决于第三方库与他们一起工作。

def f(x) -> 123:
    return x

我的总结:

Simply -> is introduced to get developers to optionally specify the return type of the function. See Python Enhancement Proposal 3107 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. 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. You can have expressions as return type (for both at function and parameter level) and the result of the expressions can be accessed via annotations object's 'return' attribute. annotations will be empty for the expression/return value for lambda inline functions.

在以下代码中:

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

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

Python还支持参数注释:

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

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

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

这些是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>

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

funcname。__annotations__将打印细节

like

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

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