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

新手上路,请多包涵

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

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

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

 def f(x) -> 123:
    return x

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

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

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

原文由 Krotton 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 517
2 个回答

这是一个 函数注释

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

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

原文由 Katriel 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

原文由 dawg 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题