-1

in these two pieces of code, why the second one gives error about local variable assignment? two codes are similar just function parameters is different, in the second one it's able to read the global variable why not in the first one what changes with parameter name change about symbol table?

first one:

def a(z):
    z+=1
z=3
a(z)

second one:

def a(z):
    b += 1
b = 5
a(b)
  • 4
    In the first one you're only updating the local variable `z` which was a function parameter. In the second one there is no such local variable so you get an error. Neither of them is updating a global variable. – khelwood Nov 27 '20 at 15:56
  • 2
    In the first one, `z+=1` increments the z parameter passed into the function. The module level z variable is not relevant. In the second one, you are attempting to increment the b variable, however, the b variable has not been declared in the function and has no value. Hence you get an error. – Tom Dalton Nov 27 '20 at 15:56
  • You need to understand a few concepts such as variable/reference, scope, and declaration/definition. – KaiserKatze Nov 27 '20 at 16:11

3 Answers3

0

You should concider def blocks as stand alone.

In the first snippet:

def a(z):
    z+=1

What is z ? It's the first parameter of a

In the second snippet:

def a(z):
    b += 1

What is b ? It is unknown. That's why this code fails.

You should also notice that in your first snippet, z inside the function is not the same than z=3:

>>> def a(z):
...     z+=1
...
>>> z=3
>>> a(z)
>>>
>>> z
3
Blusky
  • 3,470
  • 1
  • 19
  • 35
  • yes, I was just thinking why the parameter inside function does not have access to the global variable value that's why I did not get that logic about the way symbol table has been designed or the interpreter has been written, that it depends on the parameter inside function to be same name as global one to first snippet be effective or gets access to the global scope variable's value – arian yavari Nov 28 '20 at 12:49
0

There aren't any global variables in use here.

In the first example, z is a parameter to the function, not a global. Note that when you increment z, it does not change in the calling scope, because the z inside the function is a copy of the z you passed in from outside the function.

In the second example, there is no b inside the function (the parameter is z), which is why you get an error inside the function when you try to modify it.

To do what you're trying to do, you should make the parameter a mutable object that contains the value you're trying to mutate; that way you can modify the value inside the function and the caller will have access to the new value. You could define a class for this purpose, or you could simply make it a single-element list:

def a(z):
    z[0] += 1
b = [5]
a(b)  # b == [6]

Or, if possible, a better approach IMO is not to depend on mutability, and to just return the new value, requiring the caller to explicitly re-assign it within its scope:

def a(z)
    return z + 1
b = 5
b = a(b)  # b == 6
Samwise
  • 68,105
  • 3
  • 30
  • 44
  • yes, thank you I was just trying to know why in the first snippet the z inside function is able to get a copy of the global scope but not able to do so in the second code inside function where b is not able to get copy of the global scope's b variable, as you mentioned it is not a parameter for function that makes problem there, if I'm wrong please correct me. thanks – arian yavari Nov 28 '20 at 12:39
  • The important thing is that in the first snippet the `z` inside the function **is not from the global scope**. – Samwise Nov 28 '20 at 16:26
0

In the second code, the parameter is "z", and you tried to access that parameter with "b"

def a(z):
    b += 1
Merricj2
  • 43
  • 1
  • 3