2009-04-18 5 views
18

Estoy trabajando en algún código de socket Python que esté usando la función socket.fromfd().Determinar si una función está disponible en un módulo de Python

Sin embargo, este método no está disponible en todas las plataformas, por lo que estoy escribiendo algún código alternativo en el caso de que el método no esté definido.

¿Cuál es la mejor manera de determinar si un método se define en tiempo de ejecución? ¿Es suficiente lo siguiente o hay una mejor expresión idiomática?

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

estoy un poco preocupado de que la documentación de dir() parece desalentar su uso. getattr() sería una mejor opción, como en:

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

Pensamientos?

EDITAR Como Paolo señalado, esta pregunta es nearly a duplicate de una pregunta acerca de cómo determinar la presencia de atributos. Sin embargo, dado que la terminología utilizada es disjunta (lk's "el objeto tiene un atributo" frente a mi "el módulo tiene una función") puede ser útil conservar esta pregunta para buscarla, a menos que ambas puedan combinarse.

Respuesta

24

hasattr() es la mejor opción. Ve con eso. :)

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

EDITAR: En realidad, de acuerdo con los documentos de toda hasattr está haciendo está llamando getattr y agarrar la excepción. Entonces, si quieres eliminar al intermediario, debes ir con la respuesta de Marcog.

EDIT: También me acabo de dar cuenta de que esta pregunta es realmente una duplicate. Una de las respuestas allí analiza los méritos de las dos opciones que tiene: capturar la excepción ("más fácil pedir perdón que permiso") o simplemente verificar de antemano ("mirar antes de saltar"). Honestamente, soy más de lo último, pero parece que la comunidad de Python se inclina hacia la antigua escuela de pensamiento.

+0

no veo cómo esta respuesta merece un downvote ...:/ –

+1

preferiría hasattr sobre getattr sólo por el bien de la lectura! – bobince

+1

"hasattr no debe usarse porque se traga excepciones como KeyboardInterrupt". (c) http://doc.bazaar.canonical.com/developers/code-style.html#hasattr-and-getattr, por lo que 'getattr' es un buen material para hacer. –

19

o simplemente utilizar un bloque try..except:

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

Creo que lanzaría un AttributeError si no existe, no es un NameError –

+1

esta es la solución más pitonica. –

3

hasattr (obj, 'attributename') es probablemente una mejor. hasattr intentará acceder al atributo, y si no está allí, devolverá falso.

Es posible tener métodos dinámicos en python, es decir, métodos que se crean cuando intenta acceder a ellos. No estarían en dir (...). Sin embargo, hasattr lo verificaría.

>>> 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 
Cuestiones relacionadas