IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Comment tester qu'un paramètre passé à une fonction est bien une fonction


Sujet :

Python

  1. #1
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut Comment tester qu'un paramètre passé à une fonction est bien une fonction
    Bonjour,

    Je crée des fonctions destinées à une calculatrice. De ce fait, je fais systématiquement des tests de validité des paramètres passés à l'entrée de chaque fonction de calcul, et je déclenche une exception quand ce n'est pas bon.

    Or, je sais tester si le paramètre x n'est pas une chaîne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if type(x)!=str:
        raise ...
    D'ailleurs, un print type("") renvoie bien <type 'str'>

    Mais je n'arrive pas à tester si le paramètre f n'est pas une fonction alors que j'en attends une:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if type(f)!=builtin_function_or_method:
        raise ...
    déclenche toujours l'exception, même quand f est une fonction.

    Pourtant, si f est une fonction, un print type(f) renvoie <type 'builtin_function_or_method'>

    Quelqu'un sait-il comment tester si un paramètre est une fonction?

    Au pire, je pourrais toujours tester comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if type(f)!=type(len):
        raise ...
    parce que ça, ça marche puisque len est une fonction. Mais j'aimerais quelque chose de plus élégant.

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Points : 139
    Points
    139
    Par défaut
    Bonjour,

    tout d'abord, s'agit il de repérer un objet que l'on peut appeler ou bien seulement une fonction? Par exemple, int est un "type", mais on peut faire int(0).
    Bon, voici quelques pistes:
    - function callable
    - modules types avec FunctionType et BuiltinFunctionType
    - fonction isinstance, qui peut aussi détecter les instances des sous-classes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    >>> a=len
    >>> callable(a)
    True
    >>> type(a)==types.FunctionType
    False
    >>> type(a)==types.BuiltinFunctionType
    True
    >>> isinstance(len,(types.FunctionType,types.BuiltinFunctionType))
    True
    >>> callable(a)
    True
    >>> callable(int)
    True
    A noter par exemple, que comme unicode n'est pas str, j'utilise pour détecter une chaine le test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    isinstance(a,basestring)

  3. #3
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Merci Fructidor, c'est pile les réponses qu'il me fallait!

    J'ai créé une fonction pour résoudre les équations implicites (trouver x tel que f(x)=0). Tu la trouveras ici: http://python.jpvweb.com/mesrecettes...tion_implicite. Comme je veux l'intégrer dans une calculatrice, il faut que je teste si le paramètre transmis est bien une fonction de calcul (=le f(x)). L'objectif du test est de restituer à l'utilisateur un message d'erreur aussi précis que possible pour qu'il puisse corriger facilement.

    La réponse qui correspondait le mieux à ma question était: type(a)==types.FunctionType puisqu'il s'agit en général d'une fonction utilisateur (y compris définie avec lambda).

    Mais, en fait, je découvre la fonction instance en plus du module types, et la réponse plus générale que je suivrai est: isinstance(a,(types.FunctionType,types.BuiltinFunctionType))

    Merci!

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

Discussions similaires

  1. Réponses: 13
    Dernier message: 04/05/2022, 09h29
  2. Réponses: 1
    Dernier message: 22/02/2007, 14h36
  3. [ImageMagick] Savoir si une URL est bien une image
    Par Oberown dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 18/01/2006, 23h13
  4. Comment tester qu'une base est bien présente?
    Par xilay dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 20/10/2005, 16h26
  5. copie d'une table Y d'une base A vers une table X d'une base
    Par moneyboss dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 30/08/2005, 21h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo