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.
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
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
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.
Donc pour recréer cette classe GenericStore en Python
Callable[[argtype1, argtype2, argtype3], returnType]
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!