Existence of a variable in Python 2 vs 3?

Actually I have two questions about the follow code snippets:

Snippet 1:

if a:
   return 1
else:
   return 0

Snippet 2:

try:
    a = input()
except NameError:
   return 0
else:
   return 1

These two pieces of code are used to check the existence of a variable in Python. The first was used in Python 3.

My questions are:

  1. Why, when given just Enter is given as input, the first snippet returns 0 which means "does not exist", but in the second snippet of code this is the opposite and it assigns "" to the value?

  2. I'm using Python 2, so for this problem what can I do?


Solution 1:

I think you're confusing the existence of a variable and its value.

Neither snippet of code directly checks for the existence of the variable named a. The first snippets checks its value. If it doesn't exist a NameError exception will be raised.

The built-in input() function used in snippet 2, is different in Python 2 & 3.

In Python 2 it would implicitly call eval() on whatever string of characters was entered by the user—so it could raise a NameError exception if a reference to an undefined variable was given as input (such as a or b * 42).

Python 3 doesn't do that. All it does is return whatever the user typed-in as a string (without the trailing newline corresponding to the Enter the user typed on the keyboard at the end.

The following illustrates how to check for the existence of a variable (and get its value if it exists) in both Python 2 and 3. Note that it's assuming the variable a could never have a legal value of None.

def check_existence_of_a():
    try:
        return a
    except NameError:
        return None

if check_existence_of_a() is None:
    print('variable "a" does not exist')
else:
    print('variable "a" exists and its value is {}'.format(a))

a = 42

if check_existence_of_a() is None:
    print('variable "a" does not exist')
else:
    print('variable "a" exists and its value is {}'.format(a))

Output:

variable "a" does not exist
variable "a" exists and its value is 42

Update:

Using Python 2, your second code snippet could be modified as shown below to handle SyntaxErrors caused by the user typing in nothing but Enter—which happens because that then causes it to call eval(""):

def get_a():
    try:
        a = input('>')
    except SyntaxError:
        print('illegal input encountered')  # optional
        return None
    except NameError:
       return 0
    else:
       return 1

get_a()

Alternatively, you could switch from using input() to raw_input(), which does not call eval() and instead would just return the (possibly empty) string the user typed.