Private attributes and methods

Tip: Choose Save as PDF in the print dialog to download. Use A4 paper size.

Private attributes and methods

Name:
Date:
Class:

Quick Questions

Shade in the A or B circle for each question.

1. Which line creates a private attribute inside __init__?
A self.__balance = 0
B self.balance = 0
2. A class has self.__pin. What happens when outside code runs print(acc.__pin)?
A It prints the PIN
B AttributeError
3. What is name mangling?
A Python encrypts the value stored in the attribute
B Python renames __name to _ClassName__name internally
4. Which method name is private?
A def __check_pin(self):
B def check_pin(self):
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

Match the Pairs

Draw a line connecting each item on the left to its match on the right.

Left columnRight column
1self.__balance = 0 ACreates a private attribute; the double underscore makes Python name-mangle it so outside code cannot reach it directly
2def __log(self): Bprint(acc.__balance)
3Reading a private attribute from outside the class raises an AttributeError CCode 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.
4Python name-mangles a private name by changing __balance into _ClassName__balance behind the scenes DOnly 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.
5self._balance = 0 EDefines a private method that is meant to be called only from inside its own class
6acc.__balance = 50 # outside class Facc._BankAccount__balance

Definitions

self.__name

Fill in the Blanks

Complete each line of code by filling in the missing parts.

1.
self.__balance = balance
2.
def __verify(self, pin):
3.
acc = Account(50) # Outside the class: ______________ print(acc.__balance)
4.
acc = Account(50) print(acc._________________)
5.
def show(self): print(____.__balance)

Spot the Error

Shade in the letter of the line that contains an error.

Question 1
A class Bank:
B def __ok(amt):
C return amt > 0
D def pay(self, amt):
E return self.__ok(amt)
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
Question 3
A class Cat:
B __lives = 9
C def get(self):
D return self.lives
E c = Cat()
F print(c.get())
Question 4
A class Locker:
B def _init_(self, pin):
C self.__pin = pin
D def check(self, g):
E return g == self.__pin
Question 5
A class Wallet:
B def __init__(self):
C self.cash = 50
D def show(self):
E print(self.__cash)

Answer Key

Private attributes and methods
Section A: Quick Questions
Q1
A — self.__balance = 0
Q2
B — AttributeError
Q3
B — Python renames __name to _ClassName__name internally
Q4
A — def __check_pin(self):
Q5
A — Inside methods of the same class
Section B: Match the Pairs
Q1
self.__balance = 0 → Creates a private attribute; the double underscore makes Python name-mangle it so outside code cannot reach it directly
Q2
def __log(self): → Defines a private method that is meant to be called only from inside its own class
Q3
Reading a private attribute from outside the class raises an AttributeError → print(acc.__balance)
Q4
Python name-mangles a private name by changing __balance into _ClassName__balance behind the scenes → acc._BankAccount__balance
Q5
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.
Q6
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.
Section C: Definitions
Q1
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.
Section D: Fill in the Blanks
Q1
self.__balance = balance
Q2
def __verify(self, pin):
Q3
acc = Account(50) # Outside the class: AttributeError print(acc.__balance)
Q4
acc = Account(50) print(acc._Account__balance)
Q5
def show(self): print(self.__balance)
Section E: Spot the Error
Q1
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.
Q2
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.
Q3
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.
Q4
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.
Q5
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.