-1

I am new to python and I try to figure out how to pass value through functions. I have observed the following behaviors

ex1:

def func1():
    a = 1
    b.add('b')

a = 0
b = set()
func1()
print(a,b) 

the result is 0 {'b'}

Neither a nor b is declared as global, but assignment to b has changed the global value of b, is it because b is mutable variable?

ex2:

def func1():
    b.add('b')

def func2():
    b = set()
    func1()

func2()
print(b)

Traceback (most recent call last):
  File "test_variables.py", line 10, in <module>
    func2()
  File "test_variables.py", line 8, in func2
    func1()
  File "test_variables.py", line 4, in func1
    b.add('b')
NameError: name 'b' is not defined

why in this case, b cannot be assigned in func1()?

ex3:

I have to pass the variable from function to function

def func1(b):
    b.add('b')

def func2():
    b = set()
    func1(b)
    print(b)

func2()

it prints {'b'} this time

ex4:

what I can also do is to define b outside

def func1():
    b.add('b')

def func2():    
    func1()
    print(b)

b = set()
func2()

it prints {'b'} as well

thanks in advance for your kind help

4 Answers4

0

When you pass a mutable variable to a function you pass if by reference, which means you're creating another variable (which exist only in the scope of the function) which points to the same object.

Moreover, Python works in a way that you can use and see variables that are in you're outer scope (that's why in ex1 you are able to add things to

In EX1, func1() knows a and b but cannot assign values to them (unless you define them as global inside the function!). When you're doing a = 1, python just creates a new a variable that lives inside that function only.
b.add('b') is possible because you're referring to the set object (which is no mutable). If you'll try to to something like b = 'b' inside the function you will, again, create a local b variable and leave the outer set untouched.

galah92
  • 3,621
  • 2
  • 29
  • 55
0

The following is a simplified answer based on the explanation given in the Python Language Reference "Naming and Binding" document.

Let's look at your first example:

def func1():
    a = 1
    b.add('b')

You do two separate operations in this example.

First, you take the value 1 and bind it to the name a. This binding takes place in the scope that encloses its execution: In this case, the scope is the function func1.

Second, you look up the value associated with the name b and call the method add on that value. Since this is in a look up, not a binding, it is not limited to immediately enclosing scope, but will find the nearest enclosing scope that contains that name. In this case, since the scope of function func1 does not include the name b, the next enclosing scope is checked: this is the global scope, which does include the name b, and that is the value that is used.

J Earls
  • 1,792
  • 8
  • 12
0

What your asking about is called scope. Scope is a generic name for what's defined where. So when you declare a variable:

b = 0

anything at the same level of scope, or lower can see its definition.

b = 1
def func():
    print(b)

func()

This works because b has already been defined in that scope, in this instance b is global(everything can see its definition).

def func():
    b = 0

def func1():
    print(b)

func()
func1()

This will not work because b is now a local variable, its only defined in func(), not func1()

b = 1
def func():
    b = 0

def func1():
    print(b)

func()
func1()

This will print 0 because b was defined at a global level. Setting a global variable to a new value, no matter where you do that, will always make that new value available globally

But you also have to consider ordering.

print(b)
b = 1

will not work

b = 1
print(b)
b = 0

Will print b = 1 because the value wasn't set to 0, before being print

Joey Wood
  • 273
  • 1
  • 10
0

This blog post(1) explains the parameter passing of Python.

When you declare b in example 1 you declared it globally.

In example two you overwrite the name b so it is only known in func2 and thats why func1 does not know any b.

Hope this helps :)

Thalmann
  • 101
  • 3