422 votes

Types de paramètres de fonction en Python

Si je ne me trompe, la création d'une fonction en Python fonctionne comme ceci:

def my_func(param1, param2):
    # stuff

Cependant, vous n'avez pas réellement donner les types de ces paramètres. Aussi, si je me souviens, Python est un langage fortement typé, en tant que tel, il semble que Python ne devrait pas vous laisser passer un paramètre d'un type différent de la fonction de créateur prévu. Cependant, comment Python savez que l'utilisateur de la fonction est de passage dans le bon? Le programme juste mourir si c'est le mauvais type, en supposant que la fonction utilise le paramètre? Avez-vous de préciser le type?

1002voto

erb Points 618

Les autres réponses ont fait un bon travail en expliquant duck-typing et la réponse la plus simple par tzot:

Python n'a pas de variables, comme les autres langues où les variables ont un type et une valeur; il a des noms pointant vers des objets, qui connaissent leur type.

Cependant, une chose intéressante a changé depuis 2010 avec la implementaion de PEP 3107 lorsque la question est posée. Vous pouvez maintenant spécifier le type d'un attribut et le type de la valeur de retour comme ceci:

def pick(l: list, index: int) -> int:
    return l[index]

Nous pouvons ici voir qu' pick prend 2 paramètres, une liste l et un entier index. Il doit également retourner un entier.

Donc, ici, il est implicite qu' l est une liste d'entiers où l'on peut voir sans trop d'effort, mais pour des fonctions plus complexes, il peut être un peu confus quant à ce que la liste doit contenir. Nous voulons également que la valeur par défaut de index à 0. Pour résoudre ce problème, vous pouvez choisir d'écrire pick comme ceci à la place:

def pick(l: "list of ints", index: int = 0) -> int:
    return l[index]

Mais il est important de noter que Python habitude de soulever un TypeError si vous passez un flotteur en index, la raison pour cela est l'un des principaux points en Python de la philosophie de conception: "Nous sommes tous des adultes consentants ici", ce qui signifie que vous être conscient de ce que vous pouvez transmettre à une fonction et que vous ne pouvez pas. Si vous voulez vraiment écrire le type de code de sécurité, vous pouvez utiliser l' isinstance fonction pour vérifier que l'argument passé est le type approprié ou une sous-classe comme ceci:

def pick(l: list, index: int = 0) -> int:
    if not isinstance(l, list):
        raise TypeError
    return l[index]

PEP 3107 n'est pas seulement d'améliorer la lisibilité du code, mais a également plusieurs raccord usecases que vous pouvez lire ici.


Auparavant, lorsque l'on documentée code Python avec par exemple le Sphinx des fonctionnalités similaires pourraient être obtenus par l'écriture docstrings formaté comme ceci:

def pick(l, index):
    """
    :param l: list of integers
    :type l: list
    :param index: index at which to pick an integer from *l*
    :type index: int
    :returns: integer at *index* in *l*
    :rtype: int
    """
    return l[index]

Toutefois, cela prend quelques lignes, le nombre exact dépend de façon explicite que vous voulez être et comment vous format votre docstring, mais il devrait être clair pour vous comment PEP 3107 offre une alternative qui est à bien des égards supérieurs.

207voto

Alex Martelli Points 330805

Python est fortement typé, parce que chaque objet a un type, chaque objet connaît son type, il est impossible de accidentellement ou délibérément, l'utilisation d'un objet d'un type de "comme si" c'était un objet de différents type, et toutes les opérations élémentaires sur l'objet sont déléguées à son type.

Cela n'a rien à voir avec les noms. Un nom en Python n'est pas "d'avoir un type": si et quand un nom est défini, le nom se réfère à un objet, et l' objet a un type (mais cela ne veut en fait la force d'un type sur le nom: un nom est un nom est un nom).

Un nom en Python peut parfaitement bien se référer à des objets différents à des moments différents (comme dans la plupart des langages de programmation, bien que pas tous) -- et il n'y a pas de contrainte sur le nom de telle sorte que, si elle a une fois appelé à un objet de type X, il est désormais contraint de se référer uniquement à d'autres objets de type X. les Contraintes sur les noms ne font pas partie de la notion de "taper fort", même si certains amateurs de statique de frappe (d'où les noms ne obtenir de contraintes, de et en statique, en l'occurence, au moment de la compilation, de la mode, trop) faire une utilisation abusive du terme de cette façon.

21voto

TM. Points 20051

Vous ne spécifiez pas un type. La méthode échouera uniquement (au moment de l'exécution) si elle tente d'accéder à des attributs non définis dans les paramètres transmis.

Donc, cette fonction simple:

 def no_op(param1, param2):
    pass
 

... n'échouera pas quels que soient les deux arguments qui sont transmis.

Cependant, cette fonction:

 def call_quack(param1, param2):
    param1.quack()
    param2.quack()
 

... échouera au moment de l'exécution si param1 et param2 n'ont pas d'attributs appelables nommés quack .

8voto

Mark Rushakoff Points 97350

Python n'est pas fortement typé dans le sens d'une vérification de type statique ou à la compilation.

La plupart du code Python relève de ce que l'on appelle "Duck Typing" - par exemple, vous recherchez une méthode read sur un objet - vous ne vous souciez pas de savoir si l'objet est un fichier sur un disque ou un socket , vous voulez juste en lire N octets.

5voto

Kyle Points 206

Python ne se soucie pas de ce que vous transmettez à ses fonctions. Lorsque vous appelez my_func (a, b), les variables param1 et param2 contiennent alors les valeurs de a et b. Python ne sait pas que vous appelez la fonction avec les types appropriés et demande au programmeur de s'en occuper. Si votre fonction est appelée avec différents types de paramètres, vous pouvez envelopper le code en y accédant avec des blocs try / except et évaluer les paramètres comme vous le souhaitez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X