2009-04-18 20 views
18

Sto lavorando su qualche codice socket Python che utilizza la funzione socket.fromfd().Determinare se una funzione è disponibile in un modulo Python

Tuttavia, questo metodo non è disponibile su tutte le piattaforme, quindi sto scrivendo un codice di fallback nel caso in cui il metodo non sia definito.

Qual è il modo migliore per determinare se un metodo è definito in fase di esecuzione? Il seguente è sufficiente o esiste un linguaggio migliore?

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

io sono un po 'preoccupato che la documentazione per dir() sembra scoraggiare l'uso. Sarebbe getattr() essere una scelta migliore, come in:

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

Pensieri?

EDIT Come Paolo indicate, questa domanda è nearly a duplicate di una domanda sulla determinazione presenza attributo. Tuttavia, poiché la terminologia utilizzata è disgiunta (l'oggetto "lk " ha un attributo " vs mio " ha una funzione ") può essere utile conservare questa domanda per la ricerca a meno che i due non possano essere combinati.

risposta

24

hasattr() è la scelta migliore. Vai con quello. :)

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

EDIT: In realtà, secondo la documentazione tutti hasattr sta facendo sta chiamando getattr e cattura l'eccezione. Quindi se vuoi tagliare l'uomo medio dovresti andare con la risposta di Marcog.

EDIT: Ho anche appena realizzato che questa domanda è in realtà un duplicate. Una delle risposte qui discute i meriti delle due opzioni che hai: prendere l'eccezione ("più facile chiedere perdono che il permesso") o semplicemente controllare in anticipo ("guarda prima di saltare"). Onestamente, sono più di quest'ultimo, ma sembra che la comunità Python si appoggi verso la vecchia scuola di pensiero.

+0

Io non vedo come questa risposta merita un downvote ...:/ –

+1

Preferirei hasattr sopra getattr solo per amor di leggibilità! – bobince

+1

"hasattr non dovrebbe essere usato perché ingerisce le eccezioni incluso KeyboardInterrupt." (c) http://doc.bazaar.canonical.com/developers/code-style.html#hasattr-and-getattr, quindi 'getattr' è una buona roba da fare. –

19

O semplicemente utilizzare un blocco try..except:

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

Credo che genererebbe un AttributeError se non esiste, non un NameError –

+1

questa è la soluzione più pitonica. –

3

hasattr (obj, 'attributeName') è probabilmente uno migliore. hasattr proverà ad accedere all'attributo e, se non è lì, restituirà false.

È possibile avere metodi dinamici in python, ovvero i metodi creati quando si tenta di accedervi. Non sarebbero in dir (...). Comunque hasattr avrebbe controllato per questo.

>>> 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 
Problemi correlati