python3 -c "help(locals)"
says this about the locals
function:
locals()
Return a dictionary containing the current scope's local variables.
That means that calling locals()
in b()
will only show you which variables are local to b()
. That doesn't mean that b()
can't see variables outside its scope -- but rather, locals()
only returns information for variables local to b()
.
What you probably want is to make b()
show information on the variables of the calling function. To do that, take this code (which show's b()
's local variables):
def a():
x = 1
def b():
print(locals())
b()
and replace it with this one (which uses the inspect
module to get you the local information of the calling frame):
def a():
x = 1
def b():
import inspect
print(inspect.currentframe().f_back.f_locals)
b()
As for your other issue:
def a():
x = 1
def b():
a = x+2
x = 3
b()
The error you get is because Python 3 allows you to set/assign global variables and variables local to outside scopes provided you declare them with the global
and nonlocal
keywords. (I won't explain them here; I'll just say that you won't have any problem looking them up yourself.)
If you remove the x = 3
line (keeping the a = x+2
line), your code will run because x
's value is being used, but not set. If instead you remove the a = x+2
line (keeping the x = 3
line), your code will run because it will create a new x
inside b()
's scope.
If you keep both lines, Python doesn't know whether x
is supposed to refer to an x
outside the current scope (as a = x+2
seems to suggest) or if it's supposed to refer to an x
local to b()
's scope (as x = 3
suggests).
If you want x
to be local to b()
, then you shouldn't have that a = x+2
line there, at least not before x
is set with x = 3
. But if you want x
to be a()
's x
, then you should declare x
as nonlocal
to b()
, like this:
def a():
x = 1
def b():
nonlocal x # use a()'s x
a = x+2
x = 3
b()
If you're confused, remember that Python will let you use global variables and variables created outside of your current scope, but only if you don't assign to them. (It's often acceptable to read global variables, but it's frowned upon to set them.)
If you want to set a global variable or a non-local variable, you will have to declare those variables with global
(for global variables) or nonlocal
(for non-local variables), as shown in the above code.
I hope this helps.