122 votes

Comment vérifier si une méthode existe en Python ?

Dans la fonction __getattr__() Si une variable référencée n'est pas trouvée, il y a une erreur. Comment puis-je vérifier si une variable ou une méthode existe en tant que partie d'un objet ?

import string
import logging

class Dynamo:
 def __init__(self,x):
  print "In Init def"
  self.x=x
 def __repr__(self):
  print self.x
 def __str__(self):
  print self.x
 def __int__(self):
  print "In Init def"
 def __getattr__(self, key):
    print "In getattr"
    if key == 'color':
        return 'PapayaWhip'
    else:
        raise AttributeError

dyn = Dynamo('1')
print dyn.color
dyn.color = 'LemonChiffon'
print dyn.color
dyn.__int__()
dyn.mymethod() //How to check whether this exist or not

147voto

seriyPS Points 2485

Vérifier si la classe possède une telle méthode ?

hasattr(Dynamo, key) and callable(getattr(Dynamo, key))

ou

hasattr(Dynamo, 'mymethod') and callable(getattr(Dynamo, 'mymethod'))

Vous pouvez utiliser self.__class__ au lieu de Dynamo

27 votes

None n'est pas appelable, vous pouvez donc simplement faire callable(getattr(Dynamo, 'mymethod', None)) . J'ai utilisé cette réponse parce que mon super().mymethod() pourrait lancer AttributeError

0 votes

@sbutler Intéressant que cela fonctionne. D'après PyCharm, la signature pour getattr est def getattr(object, name, default=None): Je soupçonne que ce n'est pas exact, car si c'était le cas, je m'attendrais à ce que le fait de passer None comme troisième paramètre ne modifie pas le comportement de la fonction.

2 votes

@bszom : Dans un shell python, help(getattr) dit "Lorsqu'un argument par défaut est donné, il est retourné si l'attribut n'existe pas ; sans lui, une exception est levée dans ce cas." -- (et en effet vous pouvez vérifier que getattr lève bien une exception si l'attribut est manquant) donc clairement, quel que soit PyCharm, il se trompe.

117voto

S.Lott Points 207588

Il est plus facile de demander pardon que de demander la permission.

Ne pas vérifier si une méthode existe. Ne gaspillez pas une seule ligne de code pour "vérifier"

try:
    dyn.mymethod() # How to check whether this exists or not
    # Method exists and was used.  
except AttributeError:
    # Method does not exist; What now?

70 votes

Mais peut-être qu'il ne veut pas vraiment l'appeler, juste pour vérifier si cette méthode existe (comme c'est le cas pour moi)...

62 votes

Notez que cette opération échouera si dyn.mymethod() soulève un AttributeError même.

1 votes

Contrairement à .NET, cette méthode est en fait plus performante que la vérification de l'existence de la méthode. Je suis surpris (dans le bon sens du terme).

107voto

Michał Šrajer Points 9487

Pourquoi pas dir() fonction avant getattr() ?

>>> "mymethod" in dir(dyn)
True

12 votes

Cela ne permet pas de vérifier s'il s'agit d'une méthode ou d'une variable

1 votes

L'utilisation de dir n'est pas géniale - elle ne confirme pas que le nom est une méthode, par exemple

29voto

ShitalShah Points 2213

J'utilise la fonction d'utilité ci-dessous. Elle fonctionne sur les méthodes lambda, les méthodes de classe et les méthodes d'instance.

Méthode utilitaire

def has_method(o, name):
    return callable(getattr(o, name, None))

Exemple d'utilisation

Définissons la classe de test

class MyTest:
  b = 'hello'
  f = lambda x: x

  @classmethod
  def fs():
    pass
  def fi(self):
    pass

Vous pouvez maintenant essayer,

>>> a = MyTest()                                                    
>>> has_method(a, 'b')                                         
False                                                          
>>> has_method(a, 'f')                                         
True                                                           
>>> has_method(a, 'fs')                                        
True                                                           
>>> has_method(a, 'fi')                                        
True                                                           
>>> has_method(a, 'not_exist')                                       
False

3 votes

Cette réponse est plus appropriée (à mon avis du moins) que les autres réponses car elle n'utilise pas une approche générale (en utilisant des try ) et il vérifie chaque fois que le membre est une fonction réelle.

19voto

vint83 Points 141

Vous pouvez essayer d'utiliser le module "inspect" :

import inspect
def is_method(obj, name):
    return hasattr(obj, name) and inspect.ismethod(getattr(obj, name))

is_method(dyn, 'mymethod')

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