Globals and Locals

00:00 In the previous lesson, I showed you the basic usage of eval(). In this lesson, I’m going to show you the additional parameters for globals and locals and how to use it with the built-in eval() function.

00:12 Python tracks two sets of variables when inside of code. One is the global namespace and the other is the local namespace. Globals are accessible everywhere.

00:24 You might need to use the global keyword to get at them, but you can get at them. Locals, on the other hand, are only available within the context of the localized space.

00:35 This is typically the context of a function. You can see what’s in the global and local namespaces using the built-in functions globals() and locals().

00:46 Let me demonstrate those functions for you now. First off, globals(). What comes back is a dictionary showing you all of the things which are in scope in the global namespace.

00:58 Because I’m in the REPL and I haven’t done anything yet, what’s in here is just the system stuff. Lots of double underscore (__) references.

01:06 Now I’ll define a variable. There’s x. Running globals() again, and on the tail end of this dictionary, you can now see that there is a key named 'x' with the value of 3.

01:19 I’ve added something to the global namespace. Running the locals() function has a similar result. Now you might ask yourself, “Why is 'x': 3 here?” Well, because I’m not inside of a function, the x is in both the global and the local namespace.

01:34 The local namespace in this context is the same as the global namespace. Let me build a little function to show you the difference.

01:57 And now I’m going to run it. And here you can see the difference. The globals() section, which was printed first, now includes the 'x': 3 from the first global declaration, also the definition of the show_locals() function, and then below the line of hyphens, you can see the locals() result, which is just 'inside'.

02:18 inside is local to just the show_locals() function. It doesn’t show up in the global space and nothing from the global space shows up in the local space. Once again, here’s the signature of the eval() function.

02:31 It takes an expression, which I’ve introduced you to in previous lessons, as well as optional global and local dictionaries. These dictionaries specify the global and local context for the evaluation inside of the call. Let me show you these in practice.

02:50 First off, I need to create a couple of variables in the global namespace.

02:57 You can see 'x' and 'y' are inside of the global dictionary. If I eval("x + y")? No problem, it works, because those variables are in the global namespace.

03:09 If you do not specify the globals parameter, eval() uses the global dictionary. So it’s picking up the x and the y from the global namespace.

03:19 You can override that by passing in an explicit dictionary instead.

03:28 In this case, I’ve set the global context of x to be 50 and y to be 25. When the evaluation is run, instead of getting 300, I get 75.

03:39 The actual global namespace has not been changed—that’s only within the context of running the eval(). Let me try that again with a different dictionary.

03:50 This causes an error. The reason this causes an error is because if you specify a global dictionary, it only uses that global dictionary. So in this case, I’ve only defined x.

04:02 It does not see y from the actual global context, so within the context of eval(), y is not defined and you get a NameError.

04:17 The global dictionary can also reference things that are just specific to the eval(). The actual global namespace does not have a z inside of it, but because I’ve put it inside of this dictionary, it is within the eval() context.

04:32 Having it in the eval() context has not put it in the global namespace, but it did work inside of that eval(). The namespace context is more than just variables—it’s also functions.

04:46 Here, I’ve called the pow() function, no problem. Because I haven’t overridden the global namespace, it has access to the pow() function because the pow() function is a builtin.

04:59 Now, that’s interesting. It still worked. It turns out that builtins are a special case. If you do not explicitly override them, the eval() call automatically adds builtins to the global namespace.

05:12 So although I’ve overridden the global context here, builtins was added anyways. You can see the difference if I explicitly replace "__builtins__".

05:27 In this case, I’ve overridden that builtins call to be empty, and now pow() is no longer defined and an error happens. In addition to affecting the global namespace, you can also affect the local namespace.

05:44 This is similar to before, but this time I’m defining x inside of the local namespace and leaving the global namespace empty. The x here has picked up a value of 100 from the assignment of the first line I made in the REPL. So although that’s in the REPL’s global namespace, it’s being passed into the local namespace of the eval() function.

06:12 Just like the global context for eval(), if I only pass in the x for the local context, y will be undefined and you’ll get an error.

06:22 You might be wondering to yourself, “Why bother having both a global and local namespace?” In the case of eval(), it actually doesn’t make much difference.

06:30 But all of the functions—eval(), exec(), __import__()—anything that interprets code in Python has these namespaces. So although it doesn’t make much of a difference here, it’s there for consistency and to stop weird little corner cases if you happen to be calling a function that uses globals() underneath. One last thing to point out. Because eval() is kind of old, it doesn’t actually support keyword arguments passed in.

07:00 Specifying locals explicitly doesn’t work. If you want to set a value for locals, you have to pass in globals as well, which is why I’ve been passing in that empty dictionary when I was showing you how to use locals up until now.

07:15 That’s enough now about the global and local contexts. Next up, I’ll show you different kinds of expressions and how to use them with eval().

Become a Member to join the conversation.