AlastairG
AlastairG

Reputation: 4314

Python name is not defined but does evaluate to true. How?

I have some python code like this:

try:
    bob = bob_module.Bob('alpha')
except Exception as e:
    print 'Alpha mode failed for bob: '  + str(e) + ').'

try:
    if bob:
        bob.add('Beta')
    else:
        bob = bob_module.Bob('Beta')
except Exception as e:
    print 'Beta mode failed for bob: ' + str(e) + ').'

When this code ran Alpha mode failed, for an understandable reason (interaction with alpha server failed). However beta mode failed for the reason "name 'bob' is not defined".

Surely if name bob is not defined then if bob equates to false, we drop into the else clause and run the Bob constructor assigning the result to the variable bob?

I cannot now debug this because the error that caused Alpha mode to fail was transient and has now gone away, but I would like to understand this for two reasons: intellectual curiosity, and to make my code robust in case alpha mode starts failing again.

Upvotes: 3

Views: 677

Answers (2)

zwer
zwer

Reputation: 25809

When you do:

bob = bob_module.Bob('alpha')

Python will not reach the assignment phase (assigning return from the failed function call) - it will skip directly to the exception capture phase.

Since bob remains undefined, when you try to use it later in the statement:

if bob:

Python doesn't know what bob is, let alone if it would evaluate to True or False so it pops another error.

If you want to have bob pre-defined regardless of the first function's execution outcome, just assign None to it before the function call so that Python knows that bob is None and thus can properly evaluate it in the if statement no matter of what happened before.

UPDATE - In case you really don't want to define your bob beforehand, you can still check for its existence with something like:

if "bob" in globals():  # replace globals() with locals() for the current scope

or to check if it both exists and evaluates to True:

if globals().get("bob", None):  # replace globals() with locals() for the current scope

Upvotes: 2

user94559
user94559

Reputation: 60153

Surely if name bob is not defined then if bob equates to false

No. If bob is not defined, then trying to use it is an error.

Put bob = None at the top of your file to make sure it's defined in all code paths.

Upvotes: 6

Related Questions