Python Progamming/Python Language Foundations

Python Identifiers and Naming Rules

Updated 3/5/2026
1 min read

In the previous article, you explored Python keywords — the reserved words that define control flow, abstraction, and structure. Those words belong to the language itself.

Identifiers are different. Identifiers are the names you define. They represent variables, functions, classes, modules, and objects in your program.

When you write:

total = 100

total is not a container that stores the number 100. It is a name that refers to an object in memory. This distinction matters. In Python, names are references. They bind to objects.

Understanding identifiers means understanding how Python connects symbols in your code to actual objects during execution.

What Makes a Valid Identifier

Python enforces strict rules about how identifiers are formed. These rules are checked at the code-reading stage, before execution begins.

An identifier must begin with a letter (a–z or A–Z) or an underscore. After the first character, it may include letters, digits, or underscores. It cannot begin with a digit, and it cannot be a reserved keyword. Identifiers are also case-sensitive, which means total, Total, and TOTAL are three different names.

For example:

price = 100        # valid
_total = 200       # valid
user1 = "Mohan"    # valid
1user = "Error"    # invalid
class = 10         # invalid (keyword)

If a name violates these rules, Python raises a syntax error before the program can run.

These rules are not stylistic preferences. They are structural constraints of the language.

Identifiers and Naming Conventions

Beyond the syntactic rules, Python follows widely accepted naming conventions defined in PEP 8. These conventions are not enforced by the interpreter, but they communicate structure and intent clearly.

Functions and variables typically use lowercase words separated by underscores, such as calculate_total or user_name. Classes use capitalized words, such as UserAccount or OrderService. Constants are usually written in uppercase, such as MAX_RETRY_LIMIT.

These conventions make large systems readable. When naming is consistent, you can recognize the role of an object without reading its implementation.

Naming is not cosmetic. It is structural communication.

Namespaces — Where Identifiers Live

When you define an identifier, Python stores that name in a namespace. A namespace is essentially a mapping between names and objects.

There are multiple layers of namespaces in Python. When the interpreter encounters a name, it searches in a specific order: first in the local scope, then in any enclosing scopes, then in the global scope, and finally in the built-in namespace. This search order is often summarized as LEGB: Local, Enclosing, Global, Built-in.

Consider this example:

x = 10

def outer():
    x = 20
    def inner():
        print(x)
    inner()

outer()

Here, the inner function prints 20, not 10. Python resolves the name x by looking in the enclosing scope before the global scope.

Understanding this resolution process is critical when debugging unexpected behavior. Many subtle bugs arise from misunderstanding where a name is being resolved.

Name Binding and Object Identity

Assignment in Python does not copy values. It binds names to objects.

a = 10
b = a

Both a and b refer to the same object. If the object is immutable, like an integer, reassigning one name does not affect the other:

a = 15

Now a refers to a new object, while b still refers to the original 10.

With mutable objects, such as lists, multiple names can reference the same underlying object. Changes through one name affect the other:

numbers = [1, 2, 3]
alias = numbers
alias.append(4)

Now both numbers and alias refer to [1, 2, 3, 4].

Identifiers do not hold data. They reference objects. This principle becomes extremely important in functions, data structures, and object-oriented programming.

Shadowing and Name Conflicts

Because names are resolved through layered namespaces, conflicts can occur. If you assign a name that matches a built-in function, you override it within that scope.

For example:

print = "Hello"

After this assignment, attempting to call print() will fail, because the name now refers to a string instead of the built-in function.

This is called shadowing. While Python allows it, careless shadowing can introduce confusing bugs. Professional developers avoid using names that collide with built-in identifiers like list, dict, or str.

Names carry responsibility.

How Identifiers Shape Real Applications

In large systems, naming reflects architecture. Clear identifiers reveal the domain model. Service classes, repository objects, configuration constants, and data models communicate intent through naming. A poorly named function obscures logic. A clearly named abstraction clarifies design. Beyond readability, identifier management affects scope control, encapsulation, and dependency clarity. When names are carefully chosen and properly scoped, systems become easier to extend and debug.

Identifiers are the bridge between human understanding and runtime memory.

Why Identifiers Matter

Identifiers are more than variable names. They are references managed through structured namespaces. They determine how objects are accessed, how scope behaves, and how state is preserved or modified.

Once you understand that identifiers bind to objects dynamically and are resolved through layered lookup rules, Python becomes less mysterious. Scope-related bugs become explainable. State behavior becomes predictable. Names are not just labels. They are the mechanism through which your program connects meaning to memory.

What Comes Next

Now that you understand how names are formed and how they bind to objects, the next step is to examine how developers communicate intent within code.

In the next article, you will explore Comments and Documentation in Python, and how disciplined documentation supports clarity, collaboration, and long-term maintainability. Because writing correct code is not enough. Writing understandable code is what makes systems sustainable.

Python Identifiers and Naming Rules | Learn Syntax | Learn Syntax