Loading video player…

Understanding Scope in Python

00:00 Naming things is hard. What’s even harder is remembering the names you’ve used and trying not to reuse them. And if you’ve ever Googled your own name, you probably know that names aren’t necessarily unique.

00:11 So how does this apply to programming and Python? Well, when you initialize a variable or define a function, you need a name to access that variable or function with later on.

00:21 If names had to be unique across an entire program, it might be manageable at a small scale, but it would become unwieldy as the program expands. This is where scope comes in. Scope is like context.

00:32 Each line of code runs in a particular context, be it the top level of a module, or inside a function, or inside a class, etc. Scopes define areas in your code where you can access variables and names, and what happens if you use the same name multiple times?

00:48 That’s called a name collision and it can lead to buggy or outright broken code. Using scopes, you can mitigate name collisions across your programs. Another important element of software design is isolation.

01:00 A function or class should only have access to the data it needs. With scopes, you can set boundaries to control the data that certain areas of code can access.

01:09 In short, scopes are a core concept important for effectively structuring your programs.

01:15 And where do these names come from? How do they enter your program?

01:20 For names that you the programmer define, there are a few different ways they can be created in Python. Through assignment such as creating a variable like x = value, through import operations, such as import module or from module import name, in function definitions using the def keyword, for example, my_func(), followed by some function code, or in function argument definitions, which creates variables local to that function.

01:45 More on this later. For example, def my_func() and including argument names like arg1, arg2, up to argN. And of course, through class definitions using the class keyword.

01:58 Once you have a name defined, how does Python retrieve its associated object? Ah, this is where the LEGB rule comes in. At any point in the execution of your program, there can be up to four active scopes: local, enclosing, global, and built-in.

02:16 And this order is also the rule for name lookups. When you reference a name, Python searches these scopes in order for an object corresponding to that name.

02:25 If the name isn’t found in any scope, a NameError is raised. Whoops. So first we have the local, or function scope. This contains the names defined inside functions.

02:35 Next up is the enclosing, also called non-local scope. This exists for nested or inner functions, and covers the names contained in their enclosing functions.

02:46 This is probably the trickiest scope, but mastering it enables some really powerful design patterns. Then we have the global or module scope, which includes names defined at the top level of a Python script or module.

02:59 This scope is always available, meaning these names can be used anywhere.

03:04 And the built-in scope. The built-in scope is a special scope loaded at runtime, providing access to Python built-ins. The stuff in the Python standard library that’s so useful, you shouldn’t even need to import it.

03:16 And just like the global scope, this scope is available anywhere in your code.

03:21 And due to this nesting relationship, variables included in the higher scopes can be read from lower scopes, but usually can’t be modified. There are ways around this, as you’ll see in later lessons.

03:33 And another quality of these layers of scopes is that the same name can also be reused across different scopes and refer to different objects. In theory, you can have a local variable named banana as well as a global variable, also named banana.

03:49 Because this can lead to confusion, this is generally considered a bad practice no matter how much you like bananas.

Become a Member to join the conversation.