1

Look at this very basic code:

s2 = 'prefixe'
cpt = 1

def test():
    cpt += 1
    str = "%s%d" % (s2,cpt)
    print(str)

test()

I have an error. It says that cpt is read before assignment. It is normal to my opinion because cpt should be declared as a global variable:

s2 = 'prefixe'
cpt = 1

def test():
    global cpt
    cpt += 1
    str = "%s%d" % (s2,cpt)
    print(str)

test()

In this case, i have no error and the program works fine.

But, why there is no error for s2 variable ? This variable should be declared as a global variable too ? Why do not i have error ?

Thanks

Bob5421
  • 7,757
  • 14
  • 81
  • 175

2 Answers2

2

From the Python Docs

In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.

Since s2 is only read (not assigned) inside the function it's implicitly global, and there is no error. However, if you tried to modify s2 it would throw an error unless you define it as global, since by default it would assume the variable is local, and there isn't a local variable named s2.

Personally, I agree that this is a bit unintuitive.

Aaron N. Brock
  • 4,276
  • 2
  • 25
  • 43
  • 1
    "if you tried to set s2 to something it would throw an error because then python would assume it's a local variable": no it would create a second `s2`, not modifying the global `s2`. You probably mean something like `s2 += "ddd"` (which doesn't work), but `s2 = "ddd"` doesn't crash. It just doesn't modify the global – Jean-François Fabre Mar 27 '18 at 18:57
  • @Jean-FrançoisFabre you are correct, I changed the wording to "modify" instead of set. – Aaron N. Brock Mar 27 '18 at 19:03
  • also note that modifying `s2` internally creates a new reference (but that's transparent. If you write `s2 = s2 + "foo"` it uses global `s2` and creates a local `s2` ... headache :) – Jean-François Fabre Mar 27 '18 at 19:04
  • @Jean-FrançoisFabre It is really annoying... I removed the 'at first' as well since, I agree, it's still unintuitive! – Aaron N. Brock Mar 27 '18 at 19:08
1

You can refer this:

Using global variables in a function other than the one that created them

You can use a global variable in other functions by declaring it as global in each function that assigns to it:

s2 = 'prefixe'    
cpt = 1

def test():
    global cpt # Needed to modify global copy of cpt
    cpt += 1
    str = "%s%d" % (s2,cpt) # No need for global declaration to read value
    print(str)

test()

I imagine the reason for it is that, since global variables are so dangerous, Python wants to make sure that you really know that's what you're playing with by explicitly requiring the global keyword.

Vishal Taj PM
  • 1,339
  • 11
  • 23