What does -> mean in Python function definitions?

后端 未结 8 1613
我寻月下人不归
我寻月下人不归 2020-11-22 07:29

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

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


        
8条回答
  •  [愿得一人]
    2020-11-22 07:52

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

    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:

    >>> rd={'type':float,'units':'Joules','docstring':'Given mass and velocity returns kinetic energy in Joules'}
    >>> def f()->rd:
    ...    pass
    >>> f.__annotations__['return']['type']
    
    >>> 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: 
    

提交回复
热议问题