Określ czy zmienna jest zdefiniowana w Pythonie [duplikat]

Możliwy duplikat:
łatwy sposób sprawdzenia, czy zmienna jest zdefiniowana w Pythonie?
Jak sprawdzić, czy zmienna istnieje w Pythonie?

Skąd wiesz, czy zmienna została ustawiona w określonym miejscu w kodzie podczas wykonywania? Nie zawsze jest to oczywiste, ponieważ (1) zmienna może być warunkowo ustawiona, a (2) zmienna może być warunkowo usunięta. Szukam czegoś takiego jak defined() w Perlu lub isset() w PHP lub defined? w 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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-17 16:36:17

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

Jeśli chcesz być pedantyczny, możesz też sprawdzić wbudowane
'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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-12 23:47:52

Myślę, że lepiej unikać sytuacji. Jest czystsze i wyraźniejsze do napisania:

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/doraprojects.net/template/agent.layouts/content.php on line 54
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/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-20 06:47:26

Jedna możliwa sytuacja, w której może to być potrzebne:

Jeśli używasz finally block do zamykania połączeń, ale w bloku try, program kończy z sys.exit() przed zdefiniowaniem połączenia. W tym przypadku zostanie wywołany Blok finally i instrukcja zamknięcia połączenia zakończy się niepowodzeniem, ponieważ nie zostało utworzone żadne połączenie.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-28 14:20:36

W tym konkretnym przypadku lepiej zrobić a = None zamiast del a. Spowoduje to zmniejszenie liczby referencji do obiektu a, do którego został (jeśli istnieje) przypisany i nie zakończy się niepowodzeniem, gdy a nie jest zdefiniowany. Zauważ, że del instrukcja nie wywołuje destruktora obiektu bezpośrednio, ale odcina go od zmiennej. Destruktor obiektu jest wywoływany, gdy liczba referencji stała się zerem.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-20 06:30:24

Jeśli ktoś chce złapać próby uzyskania dostępu do nieokreślonej zmiennej wewnątrz obiektu, jest bardzo łatwy sposób na to:

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

Tutaj python najpierw próbuje znaleźć atrybut wewnątrz obiektu lub drzewa obiektów i tylko wtedy, gdy to nie powiedzie się wywołanej funkcji __getattr__(self, key). Oznacza to, że jeśli __getattr__ jest wywołane, możemy po prostu zwrócić 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/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-14 22:14:51