Maison >développement back-end >Tutoriel Python >Annotation de fonctions en Python

Annotation de fonctions en Python

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-27 20:36:11820parcourir

Annotating Functions in Python

Je viens de publier un blog sur les fonctions d'annotation dans Typescript. Je viens de terminer une petite étude et j'ai mieux compris comment annoter des fonctions en Python et ce blog sera consacré à l'annotation de fonctions Python avec des exemples similaires au dernier blog.

Vous pouvez valider vos annotations de type dans Visual Studio Code en définissant python.analysis.typeCheckingMode sur l'un des paramètres de base, standard, strict. Les options de base et standard ne garantissent pas nécessairement que vous annotiez vos fonctions et variables, mais strictes le fait.

Valeurs de fonction

Cela pourrait vous choquer mais vous pouvez renvoyer des fonctions et transmettre des fonctions comme valeurs en Python. Les fonctions de rappel sont en fait annotées à l'aide du type Callable qui s'écrit ainsi ;

Callable[[argtype1, argtype2, argtype3], returnType]

Par exemple, une fonction length(text: str) -> int sera annoté comme Callable[[str], int]

Par exemple ;

Cette fonction en JavaScript

function multiplier(factor){
    return value => factor * value
}

const n = multiplier(6)
n(8) // 48

peut être écrit comme ça en Python

def multiplier(factor):
    def inner(value):
        return value * factor
    return inner     

n = multiplier(6)
n(8) #48

Nous pouvons créer un TypeAlias ​​appelé number qui est une Union (littéralement) à la fois d'un int et d'un float comme ;

from typing import TypeAlias, Union

number: TypeAlias = Union[int, float]

Pour aborder les paramètres sous forme de numéros JavaScript.

Donc donc, pour annoter cette fonction, on a ;

def multiplier(factor: number) -> Callable[[number], number]:
    def inner(value: number) -> inner:
        return value * factor
    return inner

a = multiplier(4.5)
a(3) #13.5

Fonctions génériques

L'exemple de fonction générique classique est

def pick(array, index):
    return array[index]

pick([1,2,3], 2) #3

En utilisant TypeVar, nous pouvons désormais créer du verbeux générique (plus verbeux que dactylographié).

from typing import TypeVar

T = TypeVar("T") # the argument and the name of the variable should be the same

pour que nous ayons

from typing import TypeVar, Sequence

def pick(array: Sequence[T], index: int) -> T:
    return array[index]

print(pick([1,2,3,4], 2))

Alors qu'en est-il d'une fonction myMap personnalisée qui agit comme une carte en JavaScript. tel que nous avons ;

Rappelez-vous : map() en Python renvoie un type Itérable et non un type Liste

def myMap(array, fn):
    return map(fn, array)

def twice(n): return n * 2
print(myMap([1,2,3], twice))

Nous pouvons utiliser un mélange de types Callable et TypeVar pour annoter cette fonction. Observez...

from typing import TypeVar, Iterable, Callable

Input = TypeVar("Input")  # Input and "Input" must be the same
Output = TypeVar("Output")

def myMap(array: Iterable[Input], fn: Callable[[Input], Output]) -> Iterable[Output]:
    return map(fn, array)

def twice(n: int) -> int: return n * 2
print(myMap([1,2,3], twice))

ou on peut alias la fonction Callable

from typing import TypeVar, Iterable, Callable

Input = TypeVar("Input")
Output = TypeVar("Output")

MappableFunction = Callable[[Input], Output]

def myMap(array: Iterable[Input], fn: MappableFunction[Input, Output]) -> Iterable[Output]:
    return map(fn, array)

Observez que MappableFunction prend ces types génériques Input et Output et les applique au contexte de Callable[[Input], Output].

Prenez une minute pour réfléchir à la manière dont la fonction myFilter sera annotée ?

Eh bien, si vous y pensiez

from typing import Iterable, TypeVar, Callable

Input = TypeVar("Input")

def myFilter(array: Iterable[Input], fn: Callable[[Input], bool]) -> Iterable[Input]:
    return filter(fn, array)

Tu as raison

Cours génériques

Je sais que je ne suis pas censé parler d'annotation de classe, mais donnez-moi un peu de temps pour expliquer les classes génériques.

Si vous veniez du vers Typescript, c'était ainsi que vous les définiriez

class GenericStore<Type>{
    stores: Array<Type> = []

    constructor(){
        this.stores = []
    }

    add(item: Type){
        this.stores.push(item)
    }
}

const g1 = new GenericStore<string>(); //g1.stores: Array<string>
g1.add("Hello") //only string are allowed

Mais en Python, ils sont plutôt différents et gênants.

  • On importe d'abord le type Generic, puis on en fait l'enfant de la classe Generic

Donc pour recréer cette classe GenericStore en Python

Callable[[argtype1, argtype2, argtype3], returnType]

Pourquoi devrais-je apprendre à annoter des fonctions en Python ?

Comme je l'ai dit dans le blog précédent, cela aide à construire un système de saisie beaucoup plus intelligent, ce qui à son tour réduit vos risques de bugs (surtout lorsque vous utilisez des vérificateurs de fichiers statiques comme mypy). De plus, lors de l'écriture de bibliothèques (ou SDK) l'utilisation d'un système de type robuste peut améliorer légèrement la productivité du développeur utilisant la bibliothèque (principalement grâce aux suggestions de l'éditeur)

Si vous avez des questions ou s'il y a des erreurs dans cette rédaction, n'hésitez pas à les partager dans les commentaires ci-dessous ⭐

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn