2009-04-18 17 views
18

Ich arbeite an einem Python-Socket-Code, der die socket.fromfd()-Funktion verwendet.Ermitteln, ob eine Funktion in einem Python-Modul verfügbar ist

Diese Methode ist jedoch nicht auf allen Plattformen verfügbar, daher schreibe ich einen Fallback-Code für den Fall, dass die Methode nicht definiert ist.

Was ist der beste Weg festzustellen, ob eine Methode zur Laufzeit definiert ist? Ist das Folgende ausreichend oder gibt es ein besseres Idiom?

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

Ich bin etwas besorgt, dass die Dokumentation für dir() scheint seine Verwendung zu verhindern. Wäre getattr() eine bessere Wahl sein, wie in:

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

Gedanken?

EDIT Wie Paolo wies darauf hin, diese Frage ist nearly a duplicate eine Frage über Attribut Präsenz zu bestimmen. Da die verwendete Terminologie jedoch disjunkt ist (lk's "Objekt hat ein Attribut" vs mein "Modul hat eine Funktion") kann es hilfreich sein, diese Frage für die Durchsuchbarkeit zu bewahren, es sei denn, die beiden können kombiniert werden.

Antwort

24

hasattr() ist die beste Wahl. Geh damit. :)

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

EDIT: Eigentlich die Dokumentation nach allen hasattr ruft getattr tut und die Ausnahme zu kontrollieren. Wenn du also den mittleren Mann ausschneiden willst, solltest du mit Marcogs Antwort gehen.

BEARBEITEN: Ich habe auch gerade festgestellt, diese Frage ist eigentlich eine duplicate. Eine der Antworten beschreibt die Vorzüge der beiden Möglichkeiten, die Sie haben: die Ausnahme fangen ("leichter um Vergebung bitten als Erlaubnis") oder einfach vor der Hand prüfen ("Schau, bevor du springst"). Ehrlich gesagt, bin ich eher Letzterer, aber es scheint, als würde sich die Python-Gemeinschaft der früheren Denkschule beugen.

+0

Ich sehe nicht, wie diese Antwort ein downvote verdient ...:/ –

+1

ich hasattr über getattr nur willen zur besseren Lesbarkeit lieber! – bobince

+1

"hasattr sollte nicht verwendet werden, da es Ausnahmen einschließlich KeyboardInterrupt verschluckt." (c) http://doc.bazaar.canonical.com/developers/code-style.html#hasattr-and-getattr, also ist "getattr" eine gute Sache. –

19

Oder einfach einen try..except Block verwenden:

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

Ich glaube, das würde einen AttributeError auslösen, wenn er nicht existiert, kein NameError –

+1

Dies ist die pythischste Lösung. –

3

hasattr (obj, 'attribut') ist wahrscheinlich eine bessere. hasattr versucht, auf das Attribut zuzugreifen, und wenn es nicht vorhanden ist, gibt es false zurück.

Es ist möglich, dynamische Methoden in Python zu haben, d. H. Methoden, die erstellt werden, wenn Sie versuchen, auf sie zuzugreifen. Sie wären nicht in dir (...). Allerdings würde hasattr das überprüfen.

>>> 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 
Verwandte Themen