2009-04-18 10 views
18

Je travaille sur un code de socket Python qui utilise la fonction socket.fromfd().Détermine si une fonction est disponible dans un module Python

Cependant, cette méthode n'est pas disponible sur toutes les plates-formes, donc j'écris un code de secours dans le cas où la méthode n'est pas définie.

Quelle est la meilleure façon de déterminer si une méthode est définie lors de l'exécution? Est-ce suffisant ou existe-t-il un meilleur idiome?

if 'fromfd' in dir(socket): 
    sock = socket.fromfd(...) 
else: 
    sock = socket.socket(...) 

Je suis un peu inquiet que la documentation pour dir() semble décourager son utilisation. Serait getattr() être un meilleur choix, comme dans:

if getattr(socket, 'fromfd', None) is not None: 
    sock = socket.fromfd(...) 
else: 
    sock = socket.socket(...) 

pensées?

EDIT Comme Paolo a souligné, cette question est nearly a duplicate d'une question sur la détermination de la présence d'attributs. Cependant, puisque la terminologie utilisée est disjointe (l'objet de lk "lk" a un attribut " vs mon module " a une fonction ") il peut être utile de conserver cette question pour la recherche à moins que les deux puissent être combinés.

Répondre

24

hasattr() est le meilleur choix. Vas-y avec ça. :)

if hasattr(socket, 'fromfd'): 
    pass 
else: 
    pass 

EDIT: En fait, selon les docs tout hasattr fait appelle getattr et attraper l'exception. Donc, si vous voulez couper l'homme du milieu, vous devriez aller avec la réponse de Marc.

EDIT: Je viens aussi de réaliser que cette question est en fait duplicate. Une des réponses aborde les mérites des deux options que vous avez: attraper l'exception («plus facile de demander pardon que la permission») ou simplement vérifier auparavant («regardez avant de sauter»). Honnêtement, je suis plus de ce dernier, mais il semble que la communauté Python se penche vers l'ancienne école de pensée.

+0

Je ne vois pas comment cette réponse mérite une downvote ...:/ –

+1

Je préfère hasattr sur getattr juste pour l'amour de lisibilité! – bobince

+1

"hasattr ne doit pas être utilisé car il avale des exceptions, y compris KeyboardInterrupt." (c) http://doc.bazaar.canonical.com/developers/code-style.html#hasattr-and-getattr, donc 'getattr' est une bonne chose à faire. –

19

Ou tout simplement utiliser un bloc try..except:

try: 
    sock = socket.fromfd(...) 
except AttributeError: 
    sock = socket.socket(...) 
+0

Je crois que cela lancerait un AttributeError s'il n'existe pas, pas un NameError –

+1

c'est la solution la plus pythonique. –

3

hasattr (obj, 'attributename') est probablement un meilleur. hasattr va essayer d'accéder à l'attribut, et s'il n'y est pas, il retournera false.

Il est possible d'avoir des méthodes dynamiques en python, c'est-à-dire des méthodes qui sont créées lorsque vous essayez d'y accéder. Ils ne seraient pas en dir (...). Cependant hasattr vérifierait pour cela.

>>> class C(object): 
... def __init__(self): 
...  pass 
... def mymethod1(self): 
...  print "In #1" 
... def __getattr__(self, name): 
...  if name == 'mymethod2': 
...  def func(): 
...   print "In my super meta #2" 
...  return func 
...  else: 
...  raise AttributeError 
... 
>>> c = C() 
>>> 'mymethod1' in dir(c) 
True 
>>> hasattr(c, 'mymethod1') 
True 
>>> c.mymethod1() 
In #1 
>>> 'mymethod2' in dir(c) 
False 
>>> hasattr(c, 'mymethod2') 
True 
>>> c.mymethod2() 
In my super meta #2 
Questions connexes