← VCE Software Development U4O1

Private attributes and methods

A private attribute: the double underscore makes Python name-mangle it, so code outside the class cannot reach it directly and gets an AttributeError.

Understanding Private attributes and methods in VCE Software Development U4O1

What it does: Outside the class the name __balance does not exist because Python mangled it, so this line causes an AttributeError. A private attribute starts with a double underscore, like self.__balance. A single name with no underscores is public. Name mangling only changes the attribute's name, for example __name becomes _Student__name. The value is not encrypted.

Common mistakes: A private method is still a method, so its first parameter must be self. It should be def __ok(self, amt):. Without self, calling self.__ok(amt) passes too many arguments and causes an error. This is not a plain assignment, so it does not store the intended value. The private attribute should be created with a simple assignment: self.__age = 0. Otherwise get_age() would return the wrong value.

Class: _____________________  ·  Name: _____________________  ·  Date: _________

Free printable worksheet with full answer key — or add this module to a class and your students practise it interactively.

This module's key terms are also in a printable crossword (Modules 3–79) and word search (Modules 3–114).

Take this worksheet further — free with Cloodit

Each concept is reinforced from every angle — learned, then applied, then tested.

Learning
Duo
Which line creates a private attribute inside __init__?
self.__balance = 0self.balance = 0
Matches
self._balance = 0
↓
Only one underscore is used, so this is just a protected-by-convention name. Python does not mangle it and outside code can still read it. Use two underscores: self.__balance.
Applying
Meanings
Term
self.__name
Meaning
A private attribute: the double underscore makes Python name-mangle it, so code outside the class cannot reach it directly and gets an AttributeError.
Practice
class Account:
Testing
Gaps
self.balance = balance
Check Answer
Spots
1class Bank:
2 def __ok(amt):

Cloodit turns curriculum-aligned coding content into journeys students work through one biome at a time.

The 'Red Panda' badge — Forest Explorer, one of Cloodit's 106 collectible badges
Students earn collectable badges

Over 100 of them, across seven natural biomes.

Study Buddy
Students build a real study resource

Turns their work into revision material ready for Flash Cards and Exam study.

Diamond Dash — one of Cloodit's live, competitive Sprint games
Students lock in with Sprints

Live, competitive practice for the start of the lesson or a teacher-led lesson finisher.

A Cloodit certificate of achievement, ready to personalise and print
Custom printable certificates

Honour your top performers, or encourage a student who's trying hard — ready to print in seconds.

Quick Questions

1. Which line creates a private attribute inside __init__?
A. self.__balance = 0 ✓
B. self.balance = 0
A private attribute starts with a double underscore, like self.__balance. A single name with no underscores is public.
2. A class has self.__pin. What happens when outside code runs print(acc.__pin)?
A. It prints the PIN
B. AttributeError ✓
Python name-mangles __pin inside the class, so the name __pin does not exist outside it and an AttributeError is raised.
3. What is name mangling?
A. Python encrypts the value stored in the attribute
B. Python renames __name to _ClassName__name internally ✓
Name mangling only changes the attribute's name, for example __name becomes _Student__name. The value is not encrypted.
4. Which method name is private?
A. def __check_pin(self): ✓
B. def check_pin(self):
A double underscore at the start of a method name makes it private, so outside code cannot call it directly.
5. Where can self.__balance be used without an error?
A. Inside methods of the same class ✓
B. Anywhere in the program using the object
Methods inside the class can use self.__balance normally. Code outside the class gets an AttributeError.

Match the Pairs

self.__balance = 0 → Creates a private attribute; the double underscore makes Python name-mangle it so outside code cannot reach it directly
def __log(self): → Defines a private method that is meant to be called only from inside its own class
Reading a private attribute from outside the class raises an AttributeError → print(acc.__balance)
Python name-mangles a private name by changing __balance into _ClassName__balance behind the scenes → acc._BankAccount__balance
self._balance = 0 → Only one underscore is used, so this is just a protected-by-convention name. Python does not mangle it and outside code can still read it. Use two underscores: self.__balance.
acc.__balance = 50 # outside class → Code outside the class cannot update the private attribute by its plain name. Python creates a new separate attribute instead. Use a method inside the class to change the private value.

Key Term

self.__name
A private attribute: the double underscore makes Python name-mangle it, so code outside the class cannot reach it directly and gets an AttributeError.

Fill in the Blanks

1. self.__balance = balance
Hint: Type the prefix that makes this attribute private to the class.
2. def __verify(self, pin):
Hint: Type the prefix that makes this method private.
3. acc = Account(50) # Outside the class: AttributeError print(acc.__balance)
Hint: Type the name of the error Python raises when code outside the class tries to reach a private attribute.
4. acc = Account(50) print(acc._Account__balance)
Hint: Type the full mangled attribute name: one underscore, then the class name, then the private name with its double underscore prefix.
5. def show(self): print(self.__balance)
Hint: Type the keyword that lets code inside the class reach its own private attribute.

Spot the Error

Question 1
A class Bank:
B def __ok(amt):
C return amt > 0
D def pay(self, amt):
E return self.__ok(amt)
Line B — A private method is still a method, so its first parameter must be self. It should be def __ok(self, amt):. Without self, calling self.__ok(amt) passes too many arguments and causes an error.
Question 2
A class Pet:
B def __init__(self, n):
C self.__name = n
D self.__age = 0 if False else 1 == 1
E def get_age(self):
F return self.__age
Line D — This is not a plain assignment, so it does not store the intended value. The private attribute should be created with a simple assignment: self.__age = 0. Otherwise get_age() would return the wrong value.
Question 3
A class Cat:
B __lives = 9
C def get(self):
D return self.lives
E c = Cat()
F print(c.get())
Line D — Inside the class, __lives is name-mangled to _Cat__lives. self.lives is a different name that does not exist, so Python raises an AttributeError. It should be return self.__lives.
Question 4
A class Locker:
B def _init_(self, pin):
C self.__pin = pin
D def check(self, g):
E return g == self.__pin
Line B — The constructor must be named __init__ with two underscores on each side. With _init_, Python never runs it, so self.__pin is never created and check() raises an AttributeError.
Question 5
A class Wallet:
B def __init__(self):
C self.cash = 50
D def show(self):
E print(self.__cash)
Line C — The attribute is stored as the public name cash, not as a private attribute. show() looks for self.__cash (mangled to _Wallet__cash), which does not exist, so it raises an AttributeError. It should be self.__cash = 50.

Student with a class code? Join your class →