Determinar si la variable está definida en Python [duplicar]


Posible Duplicado:
¿Una forma fácil de comprobar que la variable está definida en Python?
¿Cómo puedo comprobar si existe una variable en Python?

¿Cómo sabe si una variable se ha establecido en un lugar particular del código en tiempo de ejecución? Esto no siempre es obvio porque (1) la variable podría ser puesta condicionalmente, y (2) la variable podría ser eliminada condicionalmente. Estoy buscando algo como defined() en Perl o isset() en PHP o defined? en Ruby.

if condition:
    a = 42

# is "a" defined here?

if other_condition:
    del a

# is "a" defined here?
Author: Community, 2009-10-20

7 answers

try:
  thevariable
except NameError:
  print "well, it WASN'T defined after all!"
else:
  print "sure, it was defined."
 504
Author: Alex Martelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-17 16:36:17

'a' in vars() or 'a' in globals()

Si quieres ser pedante, puedes comprobar los builtins también
'a' in vars(__builtins__)

 267
Author: John La Rooy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-12 23:47:52

Creo que es mejor evitar la situación. Es más limpio y claro escribir:

a = None
if condition:
    a = 42
 105
Author: divegeek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-20 05:15:44
try:
    a # does a exist in the current namespace
except NameError:
    a = 10 # nope
 12
Author: sc45,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-20 06:47:26

Una posible situación donde esto podría ser necesario:

Si está utilizando el bloque finally para cerrar conexiones pero en el bloque try, el programa sale con sys.exit() antes de definir la conexión. En este caso, se llamará al bloque finally y la sentencia de cierre de conexión fallará ya que no se creó ninguna conexión.

 5
Author: xsreality,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-28 14:20:36

Para este caso particular es mejor hacer a = None en lugar de del a. Esto disminuirá el número de referencias al objeto a al que se asignó (si hay alguno) y no fallará cuando a no esté definido. Tenga en cuenta que la instrucción del no llama directamente al destructor de un objeto, sino que lo desvincula de la variable. Destructor de objeto se llama cuando el recuento de referencia se convirtió en cero.

 4
Author: Denis Otkidach,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-20 06:30:24

Si uno quiere capturar intentos de acceder a una variable no definida dentro de un objeto, hay una forma muy fácil de hacerlo:

class Whatever(object):
  def __getattr__(self, key):
    return None

Aquí, python primero intenta encontrar un atributo dentro del objeto o del árbol de objetos, y solo si falla, se llama a la función __getattr__(self, key). Esto significa que, si se llama __getattr__, simplemente podemos devolver None.

 -3
Author: user1456683,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-14 22:14:51