The difference is that in the first one, bar variable is in a scope of the parent function, it can be used in the child function , unless you do assignment on it (This would be the case something similar to using global
variables in function) . Example -
>>> def foo(bar):
... def put():
... bar = bar + ['World']
... print(', '.join(bar))
... put()
...
>>>
>>> foo(['Hello'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in foo
File "<stdin>", line 3, in put
UnboundLocalError: local variable 'bar' referenced before assignment
In this case if you want to use the bar
and assign to it as well, you need to use the nonlocal
keyword , Example -
>>> def foo(bar):
... def put():
... nonlocal bar
... bar = bar + ['World!']
... print(', '.join(bar))
... put()
...
>>> foo(['Hello'])
Hello, World!
Whereas in the second one, bar is a local variable to the put()
function (because its an argument to it) and can be assigned without the above UnboundLocalError
, Example -
>>> def foo(bar):
... def put(bar):
... bar = bar + ['World!']
... print(', '.join(bar))
... put(bar)
...
>>>
>>> foo(['Hello'])
Hello, World!
I would prefer explicitly passing the required arguments as done in the second case.