Namespace questions: Mutable variable doesn't need to be declared as global in function?
<p>I am new to python and I try to figure out how to pass value through functions. I have observed the following behaviors</p>

<p><strong>ex1:</strong></p>

<pre><code>def func1():
    a = 1
    b.add('b')

a = 0
b = set()
func1()
print(a,b) 
</code></pre>

<p>the result is 0 {'b'}</p>

<p>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? </p>

<p><strong>ex2:</strong></p>

<pre><code>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 &lt;module&gt;
Â  Â  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
</code></pre>

<p>why in this case, b cannot be assigned in func1()? </p>

<p><strong>ex3:</strong></p>

<p>I have to pass the variable from function to function </p>

<pre><code>def func1(b):
    b.add('b')

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

func2()
</code></pre>

<p>it prints {'b'} this time</p>

<p><strong>ex4:</strong></p>

<p>what I can also do is to define b outside</p>

<pre><code>def func1():
    b.add('b')

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

b = set()
func2()
</code></pre>

<p>it prints {'b'} as well</p>

<p>thanks in advance for your kind help </p>

<p>The following is a simplified answer based on the explanation given in the <a href="https://docs.python.org/2/reference/executionmodel.html" rel="nofollow">Python Language Reference "Naming and Binding"</a> document.</p>

<p>Let's look at your first example:</p>

<pre><code>def func1():
    a = 1
    b.add('b')
</code></pre>

<p>You do two separate operations in this example.</p>

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

<p>Second, you <strong>look up</strong> the value associated with the name <code>b</code> and call the method <code>add</code> 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 <em>nearest enclosing scope</em> that contains that name.  In this case, since the scope of function <code>func1</code> does not include the name <code>b</code>, the next enclosing scope is checked: this is the global scope, which <em>does</em> include the name <code>b</code>, and that is the value that is used.</p>

python