Defining and Using Namespaces
A name in another namespace is most simply reached by qualifying it, written as namespace_name::name, as in std::cout.
Try it: Scope: Local, Enclosing, Global, Built-in
How Python looks up a name Local → Enclosing → Global → Built-in, why assigning to a name inside a function makes it local (and raises UnboundLocalError if it is read first), and what global, nonlocal and closures change.
How it works
- Before a function runs, Python marks every name assigned inside it as local to that function, unless it is declared global or nonlocal.
- Reading a name searches the local namespace, then enclosing functions, then the module's globals, then the built-ins; the first hit wins.
- A local name read before it has a value raises UnboundLocalError (Python does not fall back to the global).
- global x makes assignments go to the module namespace; nonlocal x makes them go to the nearest enclosing function.
- A function's local frame disappears when it returns, unless an inner function (a closure) still uses its variables.
Default run (10 steps): Ready: Local shadows global. Every name is looked up Local, then Enclosing, then Global, then Built-in. … Finished. Printed: inside: 99 / outside: 10.
Simplified: The lab's own small Python interpreter runs a fixed, hand-written script (you choose the variant and the values, never the code); nothing is executed as real Python. Every script was run in CPython 3.12 with the same inputs and the lab reproduces its output and error messages. Built-ins shows only the names the script used.
Loading the simulation…
Two Names That Look the Same
Imagine a program where a name is defined inside one namespace, and the code that needs it sits outside that namespace. The central question is simple to state: how does the code reach the name? Before reading on, try to work out your own answer. Think about what information the code would need to supply so that the name is found in the correct place, and not confused with a name of the same spelling somewhere else.
What do you think happens?
The expression My_code::main and the real main() both contain the word main. Which one is defined in the global namespace?
Reveal answer
The real main() is defined in the global namespace. My_code::main refers to a name inside the My_code namespace.
The qualifier is what separates the two. The same final word appears in two places, and the namespace part says which one is meant.
Reaching a Name with namespace_name::name
The most direct way to access a name in another namespace is to qualify it with the namespace name. You write the namespace name, then two colons, then the name itself. The general form is namespace_name::name. The double colon is the operator that connects the namespace on the left to the item on the right.
The source gives two examples of this form: std::cout and My_code::main. In each case the part before the double colon identifies the namespace, and the part after it identifies the name inside that namespace. Reading each expression from left to right gives you the container first and the item second.
The qualifier is what makes the reference unambiguous. The same final word can appear in more than one namespace, and the qualifier says which one you mean. This is why the qualified form is described as the most simple, direct way to reach a name in another namespace.
Where the Global Namespace Fits
The global namespace holds names that are not local to a defined namespace, class, or function. The real main() is defined there. It is not inside My_code, and it is not inside std. The diagram below shows which names live inside which containers.
Qualifying Names in a Short Program
The following small example uses qualification on every use of a standard-library name. Each line names the namespace at the point of use, so a reader can see where each name comes from without looking anywhere else.
- Each std::cout names the std namespace on the left and the item cout on the right.
- The prefix is repeated on every line that uses the name.
Reading a qualified name aloud
Read the expression std::cout and say which part is the namespace, which part is the name inside it, and what the double colon does.
- 1Find the double colon
The two colons sit between std and cout, so they divide the expression into a left part and a right part.
- 2Read the left part
std is the namespace that holds the name. It is the container.
- 3Read the right part
cout is the item inside std that is being referred to.
- 4State the meaning
The double colon connects the container to the item, so std::cout means the cout name inside the std namespace.
std is the namespace, cout is the name inside it, and the double colon links the two.
Mistakes With Qualified Names
Common mistake Treating the final word as enough to identify the name
What it looks likeReading My_code::main and assuming it is the same thing as the real main()
Why it failsThe same final word can appear in more than one namespace, so the word alone does not say which one is meant.
Do this insteadRead the qualifier as well. My_code::main is inside My_code, while the real main() is in the global namespace.
Common mistake Leaving out the qualifier when a name is not visible
What it looks likeWriting cout alone in code where only std::cout has been named
Why it failsWithout the qualifier or a using-directive, the code has no stated route to the name inside std.
Do this insteadWrite std::cout, or make the access explicit with a using-directive as covered below.
Common mistake Thinking a qualified name is spelled with a single colon
What it looks likeWriting std:cout
Why it failsThe general form is
namespace_name::name, with two colons between the parts.Do this insteadAlways write the double colon, as in std::cout.
What a Using-Directive Changes
Qualifying every use of a name works, but it can become repetitive. The source introduces a second mechanism for the standard-library namespace: the using-directive. A using-directive gives you access to names in a namespace, so that you can refer to those names without writing the qualifier each time. The conventional spelling of a using-directive for the standard namespace is shown in the code below.
- The using-directive appears once, before the lines that use its names.
- Each following line refers to cout without writing std:: in front of it.
Choosing Between the Two Techniques
Both techniques give access to a name in another namespace, so the choice is about how the code reads and how clearly it identifies its sources. Qualification names the namespace at the point of use, which makes the origin of every name obvious on the line where it appears. A using-directive omits that naming at the point of use, which is convenient when one namespace is used heavily.
A program uses cout four times and uses a single name from another namespace called My_code::main once. Would you keep the prefix on all five uses, or add a using-directive for the heavily used namespace? Explain your choice in terms of how clearly each line shows where its name comes from.
Hints
- Think about which namespace is used heavily and which is used only once.
- A line that is used only once may keep its prefix without much repetition.
Key Takeaways
- A name in another namespace is reached by qualifying it as
namespace_name::name, read from left to right, with the double colon connecting the namespace to the item inside it. - The global namespace holds names that are not local to a defined namespace, class, or function, and the real
main()is defined there, separate from names such as My_code::main. - A using-directive gives access to names in a namespace so they can be written without the qualifier, but it does not move those names out of their namespace.
- Choose qualification when the source of each name should be visible on its line, and a using-directive when one namespace is used heavily.