Variables and Naming
Assignment, dynamic typing, naming rules, and what a name really points at.
What you will be able to do
- Say what a variable is in Python, in terms of names and objects
- Create, reassign, and use variables in expressions
- Explain what dynamic typing does and does not mean
- Apply the naming rules, and know which names are illegal and why
- Assign several variables at once, and swap two without a temporary
- Use type(), isinstance(), and id() to inspect what a name refers to
- Predict what happens when two names refer to the same mutable object
The idea, in plain English
In some languages a variable is a box, and assigning to it puts a value inside. Python does not work that way, and carrying the box picture forward will make lists, dictionaries, and function arguments confusing later. It is worth replacing now.
In Python a variable is a name that refers to an object. `name = "Chandu"` creates a string object and points the name at it. The name is not the thing; it is a label attached to the thing, and the same object can have several labels.
That is why Python needs no type declaration. You never write `int age = 25`, because the type belongs to the object, not to the name. The same name can refer to an integer now and a string later - this is what dynamically typed means.
It also explains the one behaviour that surprises everyone: assignment never copies. `y = x` attaches a second label to the object x already refers to. For an integer that is harmless, because integers cannot be changed. For a list it is the source of the classic "why did my other list change" bug.
Worked example: Swapping two player names without a third variable.
What each statement actually does
Read this line by line. The column that matters is the last one - how many objects exist, and how many names are pointing at them. Nothing in this table copies anything.
x = 10Makes an int object and points the name x at it. One name, one object.x = 20The 10 is not changed - integers cannot be changed. A new object is made and x moves to it. Nothing refers to 10 any more, so Python may discard it.y = xNo copy. A second name is pointed at the object x already refers to. Two names, one object, and id(x) == id(y) proves it.numbers2 = numbers1Exactly the same thing, on a list. One list object, two names - and still nothing copied.numbers2.append(4)A list can be changed in place, and there is only one list. So numbers1 now shows [1, 2, 3, 4] as well, without ever being mentioned.numbers2 = numbers1.copy()The only line here that makes a second object. Now appending through one name leaves the other alone.Watch out: The surprise is never the assignment - it is the mutation. Two names on an int are harmless because an int can never change. Two names on a list, a dict, or a set are two ways to change one thing.
Dynamic typing, and what it does not mean
Python works out the type from the object you assign, so you write `age = 25` rather than `int age = 25`. The same name can later refer to something else entirely - an integer, then a string, then a list - and Python will not complain.
Dynamically typed does not mean untyped. Every object has a definite type and Python enforces it; `"5" + 5` is still an error. The difference is only that the check happens when the line runs rather than before the program starts.
Tip: Reusing one name for different types is legal but rarely kind to the reader. `data` holding an int, then a str, then a list is three variables wearing one name.
Constants are a promise, not a rule
Python has no const. What it has is a convention: an ALL_CAPS name says "treat this as fixed". MAX_RETRIES = 3 at the top of a file is a signal to other developers, and to you in six months.
Nothing stops you reassigning it. `MAX_RETRIES = 5` on the next line works fine. The uppercase is documentation that the language does not enforce, which makes it worth honouring rather than testing.
Syntax and examples
name = "Rahul"
age = 25
salary = 50000.50
is_active = True
print(name, age, salary, is_active)value = 100
print(type(value)) # <class 'int'>
value = "Python"
print(type(value)) # <class 'str'>
value = [1, 2, 3]
print(type(value)) # <class 'list'>price = 100
quantity = 3
total = price * quantity
print(total) # 300
score = 10
score = score + 5 # long form
score += 5 # shorthand, same thing
print(score) # 20# Several names at once
name, age, country = "Chandu", 34, "India"
# The same object to several names - useful for counters
pending = completed = failed = 0
# Swapping, with no temporary variable
player1 = "Rahul"
player2 = "Arjun"
player1, player2 = player2, player1
print(player1, player2) # Arjun Rahulage = 34
print(type(age)) # <class 'int'>
print(isinstance(age, int)) # True
print(isinstance(age, str)) # False
x = 100
y = x
print(id(x) == id(y)) # True - one object, two namesnumbers1 = [1, 2, 3]
numbers2 = numbers1 # second name, same list
numbers2.append(4)
print(numbers1) # [1, 2, 3, 4] <- not a typo
print(numbers2) # [1, 2, 3, 4]
# When you want an actual copy, ask for one:
numbers3 = numbers1.copy()
numbers3.append(5)
print(numbers1) # [1, 2, 3, 4] - untouched this timeWatch out: id() values differ between runs and between Python builds. Use them to compare two names in the same run, never as a stable identifier for anything.
Naming rules
Break any of the first three and Python raises a SyntaxError before your program runs at all.
Letters, digits, _A name may contain letters, digits, and underscores. Nothing else.
user_name, item2, _internal
Never starts with a digit2name is a syntax error. Put the digit anywhere but the front.
name2 ✓ 2name ✗
No spaces or hyphensA space ends the name; a hyphen is read as subtraction. Use underscores.
first_name ✓ first-name ✗
Not a keywordThe 35 reserved words are unavailable. A trailing underscore is the usual workaround.
class_ = "Physics"
Case sensitivename, Name, and NAME are three different variables. This catches people out in long files.
name != Name
snake_case by conventionLowercase with underscores for variables and functions; CamelCase is reserved for classes.
total_amount, not totalAmount
Functions for inspecting objects
type()The type of the object a name refers to.
type(34) # <class 'int'>
isinstance()Whether an object is an instance of a type. Preferred over type() for checks, because it accepts subclasses too.
isinstance(34, int) # True
id()Which object a name refers to. Two names with the same id refer to one object.
id(x) == id(y)
Try it yourself
The code does not change. Swap the content string and the program does something else entirely.
“v = 1; print(type(v)); v = "1"; print(type(v))”
“a = [1]; b = a; b.append(2); print(a)”
“a = [1]; b = a.copy(); b.append(2); print(a)”
“a, b, c = 1, 2, 3; a, b, c = c, a, b; print(a, b, c)”
What usually goes wrong
Python reads the digit and expects a number, then finds letters. The error points at the name itself, so this one is at least easy to spot.
✗ 1name = "Rahul"✓ name1 = "Rahul"A space ends the name and Python sees two things where you meant one. A hyphen is worse - it parses as subtraction, so the error can appear somewhere else entirely.
✗ first name = "Rahul"
user-name = "Rahul"✓ first_name = "Rahul"
user_name = "Rahul"class, from, is, and 32 others belong to the language. Rename, or append an underscore if the word is genuinely the right one.
✗ class = "Python"✓ course = "Python"x = 1000 is legal and useless. The interpreter does not care, but every person who reads it afterwards has to work out what it holds - including you.
✗ x = 1000
y = 2
z = x * y✓ product_price = 1000
quantity = 2
total_price = product_price * quantityThe big one, and the reason this lesson spends so long on names and objects. With a mutable object, two names mean one thing that both can change.
✗ list2 = list1 # same list✓ list2 = list1.copy() # a new listBest practices
- Name things after what they hold: total_price, not x. The cost of a long name is paid once; the cost of a vague one is paid on every read.
- Use snake_case for variables and functions, CamelCase for classes, ALL_CAPS for constants.
- Avoid abbreviations unless your project already uses them. customer_address beats cust_addr.
- Do not reuse one name for different types in the same function - give the second thing its own name.
- When you want a copy of a mutable object, say so explicitly with .copy() or copy.deepcopy().
- Reach for isinstance() rather than type() == when you are checking a type, because it handles subclasses correctly.
Practice
Write these yourself before opening anything. Getting them wrong first is most of how this sticks.
Create variables for your name, age, country, city, and profession, then print them all on one line.
Show hintHide hint
print() takes several arguments and separates them with spaces.
Show solutionHide solution
name = "Chandu"
age = 34
country = "India"
city = "Hyderabad"
profession = "Engineer"
print(name, age, country, city, profession)A cart holds 3 items at 1500 each. Store the price and quantity in well-named variables, work out the total, and print it.
Show solutionHide solution
product_price = 1500
quantity = 3
total_price = product_price * quantity
print("Total:", total_price) # Total: 4500Given a basic salary, a bonus, and a deduction, calculate and print the net salary.
Show hintHide hint
net = basic + bonus - deduction
Show solutionHide solution
basic_salary = 50000
bonus = 10000
deduction = 4000
net_salary = basic_salary + bonus - deduction
print("Net salary:", net_salary) # Net salary: 56000Create one variable of each type - int, float, str, bool - and print the type of each.
Show solutionHide solution
count = 10
price = 99.99
title = "Python"
is_ready = True
print(type(count)) # <class 'int'>
print(type(price)) # <class 'float'>
print(type(title)) # <class 'str'>
print(type(is_ready)) # <class 'bool'>Set a = 100 and b = 200, then swap them without creating a third variable. Print both to prove it worked.
Show hintHide hint
One line, with a comma on each side of the equals sign.
Show solutionHide solution
a = 100
b = 200
a, b = b, a
print(a, b) # 200 100Student progress calculator
Store a student, their course, and how far through it they are, then report their progress as a percentage.
- Use at least four variables, all meaningfully named
- Store the student name, course name, completed lessons, and total lessons
- Calculate the percentage from the variables, not from a hard-coded number
- Print a readable report over several lines
- Round the percentage to one decimal place
student_name = ""
course_name = ""
completed_lessons = 0
total_lessons = 0
# work out the percentage and print the reportShow one solutionHide solution
student_name = "Rahul"
course_name = "Core Python"
completed_lessons = 15
total_lessons = 75
progress = round(completed_lessons / total_lessons * 100, 1)
print("Student:", student_name)
print("Course:", course_name)
print("Completed:", completed_lessons)
print("Total:", total_lessons)
print("Progress: " + str(progress) + "%")
# Student: Rahul
# Course: Core Python
# Completed: 15
# Total: 75
# Progress: 20.0%Key points
- A variable is a name that refers to an object. It is not a box, and the difference matters from the lists lesson onward.
- Assignment binds a name to an object. It never copies.
- Python is dynamically typed: the type belongs to the object, so the same name can refer to different types over time.
- Reassigning a name does not change the old object - it points the name somewhere else.
- Names are case sensitive, cannot start with a digit, cannot contain spaces or hyphens, and cannot be keywords.
- snake_case for variables and functions, CamelCase for classes, ALL_CAPS for constants.
- a, b = b, a swaps two names with no temporary variable.
- type() gives the type, isinstance() checks it, and id() says which object a name refers to.
- Two names on one mutable object means a change through either is visible through both.
- Constants are a convention Python does not enforce - ALL_CAPS is a promise to other developers.
Quick check before you move on
Interview questions
What actually happens when you write x = 10 in Python?
Python evaluates the right-hand side to an object, then binds the name x to that object in the current namespace. The name holds a reference, not the value itself, which is why assignment is constant-time regardless of how large the object is.
Is Python statically or dynamically typed, and is it strongly or weakly typed?
Dynamically typed and strongly typed - two independent questions people often merge. Dynamic means types are checked at runtime rather than declared. Strong means Python will not quietly coerce between unrelated types: "5" + 5 raises a TypeError rather than guessing.
Why does changing one list appear to change another?
Because it is one list. Assignment binds a second name to the same object rather than copying it, and lists are mutable, so a change through either name is a change to the single shared object. The fix is an explicit copy - .copy() for a shallow one, copy.deepcopy() when it is nested.
What does id() return, and when would you use it?
An integer identifying an object for its lifetime - in CPython, its memory address. It is useful for demonstrating that two names refer to one object, and it is what the `is` operator compares. It is not stable across runs, so it is never an identifier to store.
Does Python have constants?
Not as a language feature. The convention is an ALL_CAPS name, which tells other developers not to reassign it, but nothing enforces that. Where enforcement genuinely matters people reach for other tools - a frozen dataclass, an Enum, or a module-level value behind a property.
Why does a, b = b, a work?
The right-hand side is evaluated first, building a tuple (b, a) from the current values. Only then is that tuple unpacked into the names on the left. Because the old values are already captured in the tuple, neither assignment can clobber the other.
What is snake_case, and where does the convention come from?
Lowercase words joined by underscores - first_name, total_amount. PEP 8 specifies it for variables, functions, and modules, with CamelCase reserved for classes and ALL_CAPS for constants. The value is consistency: a name’s shape tells you what kind of thing it is before you read it.
Quiz
- 1.
What is a variable in Python?
- 2.
What does it mean that Python is dynamically typed?
- 3.
After numbers2 = numbers1 and numbers2.append(4), what does numbers1 contain?
- 4.
What is the difference between type() and isinstance()?
- 5.
How do you swap two variables without a temporary?
- 6.
Which of these are invalid names, and why: 2name, user-name, class, _total?
Comments
Sign in to leave a comment. Your name and photo come from Google; nothing else is shared.
Loading comments...
AI
System Design
Backend
- GraphQL8 modules · 69 lessons planned
- Core Python13 modules · 75 lessons planned
- FastAPI5 sections · 20 lessons
- Node.js14 modules · 206 lessons planned
- Node.js Performance7 chapters · 36 topics
- Event Loop Lifecycle6 phases · 3 scenarios
- Docker & Containerization11 modules · 144 lessons planned
- AWS for Developers14 modules · 219 lessons planned
- CI/CD & DevOps Automation10 modules · 134 lessons planned