14
def say_boo_twice():
  global boo
  boo = 'Boo!'
  print boo, boo

boo = 'boo boo'
say_boo_twice()

The output is

Boo! Boo!

Not as I expected. Since I declared boo as global, why is the output not:

boo boo boo boo

Paul T.
  • 714
  • 1
  • 9
  • 20
Don Lun
  • 2,717
  • 6
  • 29
  • 35
  • 1
    That's the expected output. You assign boo, then you print it twice. – Rudolf Real May 22 '14 at 02:15
  • 1
    this is a confusing example. why not change the values rather than "say twice" for "boo boo"? muddy thinking. – dcsan Jul 08 '17 at 21:29
  • It's unclear why this question was asked, let alone how it got upvotes and an answer. Why should it matter whether `boo` is local or global - **how is it surprising** that assigning to a name and then immediately using it, results in the newly assigned value being used? I can't understand the logic behind expecting what OP expected. – Karl Knechtel Sep 09 '22 at 11:25

6 Answers6

29

You've changed boo inside your function, why wouldn't it change? Also, global variables are bad.

Dr McKay
  • 2,548
  • 2
  • 21
  • 26
  • 3
    instead of using global variables, what are the better way to handle a variable to be used across functions? – Nicholas TJ Jul 24 '12 at 15:19
  • 1
    @NicholasTJ You should ask that as a new question. I guess you could store the "global" variables in a Singleton class, or a module's dictionary - also see e.g. [here](http://stackoverflow.com/q/6255050/321973) – Tobias Kienzler Apr 11 '13 at 07:18
  • I don't know a way to use matplotlib directly without globals and side effects and order-dependent, imperative ooze. I'd suppose that Python programmers just get accustomed to that style from using matplotlib. – Reb.Cabin Feb 12 '17 at 22:02
  • are such "global" variables local to the module, or the whole system? – dcsan Aug 11 '17 at 11:48
  • 2
    why `global` variables are bad? @Dr McKay – alper Nov 26 '18 at 15:53
18

Because you reassign right before hand. Comment out boo = 'Boo!' and you will get what you describe.

def say_boo_twice():
   global boo
   #boo = 'Boo!'
   print boo, boo  

boo = 'boo boo' 
say_boo_twice() 

Also that global boo is unnecessary, boo is already in global scope. This is where the global makes a difference

def say_boo_twice():   
   global boo
   boo = 'Boo!'
   print boo, boo  

say_boo_twice() 
print "outside the function: " + boo #works

Whereas:

def say_boo_twice():   
   #global boo
   boo = 'Boo!'
   print boo, boo  

say_boo_twice() 
print "outside the function: " + boo # ERROR.  boo is only known inside function, not to this scope
Paul T.
  • 714
  • 1
  • 9
  • 20
jon_darkstar
  • 16,398
  • 7
  • 29
  • 37
5

You are re-assigning boo after you declare it as global, so the value is the last one you assigned to it. If you removed line three, you would get the output you expect.

josePhoenix
  • 538
  • 1
  • 5
  • 14
3

Essentially you reassign boo when you call the function.

Check how this works with the globals() and locals() functions.

mcpeterson
  • 4,894
  • 4
  • 24
  • 24
0

Before giving an example I want you to understand difference between global and local variable in python

global variable: This is specific to current module

local variable: This is specific to current functions or methods as we call it in python

What if both local and current variable have the same name boo ?

In such case if you don't define your variable boo as global in the same method or function it will by default use it as local variable

Coming to your code

You have defined boo as global in your method say_boo_twice(). The catch is when you try to initialize boo = 'Boo!' in that method you are actually overwriting what you initialized previously as boo = 'boo boo'

Try this code

-- I have not initialized variable boo inside method say_boo_twice()

def say_boo_twice():    
    global boo
    print boo, boo

boo = 'boo boo'    
say_boo_twice()

All the Best !!! !! !

0

global boo is global only inside method say_boo_twice and has been re-assigned a value inside of this method. You need to understand the lexical or scope where it can be global or what you want it to be. In this context, just before printing, it was assigned a value of 'Boo!' and that is what it correctly printed.

NullException
  • 4,232
  • 8
  • 24
  • 44