3

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.

AlastairG
  • 4,119
  • 5
  • 26
  • 41
  • 4
    _"Surely if name bob is not defined then if bob equates to false_" Umm, no. That's like saying "Surely if aliens don't exist, they must be green". It doesn't make any sense. If it doesn't exist, how is it supposed to evaluate to anything? – Aran-Fey Jun 26 '17 at 07:33
  • 1
    `name bob is not defined` means that `if bob` failed, not that the `else` executes. Not being defined is not the same as being `None` or `False` – Ma0 Jun 26 '17 at 07:33
  • 1
    As `bob = bob` raises an exception bob doesn't get setted. See [this answer](https://stackoverflow.com/a/25666911/4725649) – EndermanAPM Jun 26 '17 at 07:33
  • should check if bob not None: – Eliethesaiyan Jun 26 '17 at 07:34
  • @rawing, what? How is your analogy anything like the same? I am saying that if the name "bob" does not exist, i.e. if the variable does not exist or has not been created/populated, then testing for it should return false. That's more like saying that if aliens don't exist then they do not have a colour at all. – AlastairG Jun 26 '17 at 08:26
  • @Ev. Thanks. You should put that as an answer not a comment! It is exactly the what I needed to know. I think I am getting confused with Lua syntax where all undefined variables evaluate as Nil or false (I think). – AlastairG Jun 26 '17 at 08:28
  • @AlastairG You're not testing if the variable exists. What you're testing is whether the (boolean) value of the (nonexistent) variable is `True`. So it's the same thing as checking a nonexistent alien's color. – Aran-Fey Jun 26 '17 at 08:33
  • @Eliethesaiyan, You should add that as an answer so I can upvote it. Except the syntax is wrong: `if bob not None:` gives `SyntaxError: invalid syntax`. – AlastairG Jun 26 '17 at 08:34
  • @AlastairG The correct syntax is `if bob is not None:`. It's just a more specific check than what you're doing. Your check is okay (once you actually define `bob`) but checking against `None` is a little better. – user94559 Jun 26 '17 at 08:37
  • @Rawing, ah I see now. I think you meant to say "it's like asking if aliens are green when they don't exist". – AlastairG Jun 26 '17 at 08:37
  • @AlastairG i did update the right syntax in the answer section – Eliethesaiyan Jun 26 '17 at 08:38
  • Thanks to everyone for fast answers. – AlastairG Jun 26 '17 at 08:39

2 Answers2

6

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.

user94559
  • 59,196
  • 6
  • 103
  • 103
2

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
zwer
  • 24,943
  • 3
  • 48
  • 66