Wat doet -> betekenen in de functiedefinities van Python?

Ik heb onlangs iets interessants opgemerkt bij het bekijken van Python 3.3 grammaticaspecificatie:

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

Het optionele ‘pijl’-blok was afwezig in Python 2 en ik kon geen informatie vinden over de betekenis ervan in Python 3. Het blijkt dat dit de juiste Python is en wordt geaccepteerd door de interpreter:

def f(x) -> 123:
    return x

Ik dacht dat dit een soort syntaxis van een voorwaarde zou kunnen zijn, maar:

  • Ik kan xhier niet testen, omdat het nog niet gedefinieerd is,
  • Wat ik ook na de pijl plaats (bijv. 2 < 1), het heeft geen invloed op het functiegedrag.

Kan iemand die gewend is aan deze syntaxisstijl het uitleggen?


Antwoord 1, autoriteit 100%

Het is een functieannotatie.

Meer in detail, Python 2.x heeft docstrings, waarmee je een metadatastring aan verschillende soorten objecten kunt koppelen. Dit is ongelooflijk handig, dus Python 3 breidt de functie uit door je metadata toe te voegen aan functies die hun parameters beschrijven en waarden retourneren.

Er is geen vooropgezet gebruik, maar de PEP suggereert er verschillende. Een erg handige is om u in staat te stellen parameters te annoteren met hun verwachte typen; het zou dan gemakkelijk zijn om een decorateur te schrijven die de annotaties verifieert of de argumenten naar het juiste type dwingt. Een andere is om parameterspecifieke documentatie toe te staan in plaats van deze te coderen in de docstring.


Antwoord 2, autoriteit 74%

Dit zijn functieannotaties die worden behandeld in pep 3107 . Specifiek, de ->markeert de annotatie van de retourfunctie.

Voorbeelden:

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

Annotaties zijn woordenboeken, zodat u dit kunt doen:

>>> '{:,} {}'.format(kinetic_energy(12,30),
      kinetic_energy.__annotations__['return'])
'5,400.0 Joules'

U kunt ook een Python-datastructuur hebben in plaats van slechts een tekenreeks:

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'

Of u kunt functieattributen gebruiken om valideren te valideren:

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)

Afdrukken

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

Antwoord 3, autoriteit 35%

In de volgende code:

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

de -> intvertelt alleen dat f()een geheel getal retourneert (maar het dwingt de functie niet om een geheel getal terug te geven). Het wordt een return-annotatiegenoemd en is toegankelijk als f.__annotations__['return'].

Python ondersteunt ook parameterannotaties:

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

: floatvertelt mensen die het programma lezen (en sommige bibliotheken/programma’s van derden, bijv. pylint) dat xeen float. Het is toegankelijk als f.__annotations__['x'], en heeft op zichzelf geen enkele betekenis. Zie de documentatie voor meer informatie:

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


Antwoord 4

def function(arg)->123:

Het is gewoon een retourtype, integermaakt in dit geval niet uit welk getal je schrijft.

zoals Java:

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

Maar voor Python (hoe Jim Fasarakis Hilliardzei) het retourtype is het slechts een hint, dus het is een suggestie om terug te keren, maar sta hoe dan ook toe om een ander type terug te geven, zoals een string..


Antwoord 5

def f(x) -> 123:
    return x

Mijn samenvatting:

  1. Gewoon ->is geïntroduceerd om ontwikkelaars ertoe te brengen optioneel het retourtype van de functie te specificeren. Zie Python-verbeteringsvoorstel 3107

  2. Dit is een indicatie van hoe dingen zich in de toekomst kunnen ontwikkelen als Python op grote schaal wordt geadopteerd – een indicatie voor sterk typen – dit is mijn persoonlijke observatie.

  3. U kunt ook typen voor argumenten opgeven. Het specificeren van het retourtype van de functies en argumenten zal helpen bij het verminderen van logische fouten en het verbeteren van codeverbeteringen.

  4. U kunt uitdrukkingen hebben als retourtype (voor zowel op functie als parameterniveau) en het resultaat van de uitdrukkingen is toegankelijk via annotaties ‘return’ attribuut. Annotaties zijn leeg voor de expressie / retourwaarde voor Lambda Inline-functies.


6

Dit betekent het type resultaat dat de functie retourneert, maar het kan None.

Het is wijdverspreid in moderne bibliotheken georiënteerd op Python 3.x.

Het is bijvoorbeeld in de code van de bibliotheek Panda-profilering op veel plaatsen bijvoorbeeld:

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.

7

– & gt; wordt geïntroduceerd in Python3.

In eenvoudiger woorden, de inhoud na het – & GT; geeft het retourtype van de functie aan.
Het retourtype is optioneel.


8

def f(x) -> str:
return x+4
print(f(45))

geeft het resultaat: 49 .

of met andere woorden ‘- & GT; str ‘heeft geen effect op het retourtype:

print(f(45).__class__)
<class 'int'>

Other episodes