If you need help reviewing OOP, take a look at these resources:
Each question has a "Toggle Solution" button -- click it to reveal that question's solution.
Variables: Conceptual Questions
Question 1
Define each of the following terms:
- Local variable
- Instance variable
- Class variable
- Local variable: a variable that is only visible within the scope of a method. Once the method finishes executing, the local variable is erased.
Instance variable: a variable that persists — even after methods are done executing, these variables will still exist and retain their value.
- Tip: you can tell a variable is an instance variable if it
has
self.
in front of it (e.g.self.name
). - Instance variables can only be used within methods.
- Instance variables are unique to each instance of the class. They are not shared by instances.
- Tip: you can tell a variable is an instance variable if it
has
Class variable: like instance variables, class variables also persist. However, class variables ARE shared by all instances of the class.
- When initialized outside of methods (which is usually the case),
the class variable has no "dot" modifier (e.g. just
num_of_accounts
- When referenced in methods, the class variable must
be referenced with the following syntax:
class_name.variable
(e.g.Account.num_of_accounts)
- When initialized outside of methods (which is usually the case),
the class variable has no "dot" modifier (e.g. just
Question 2
Consider the following code:
class Account:
interest = 0.02
def __init__(self, name, balance):
self.name = name
self.balance = balance
def deposit(self, amt):
total = self.balance + amt
self.balance = total
Determine whether each of these variables are local, instance, or class variables:
name
self.name
balance
self.balance
interest
amt
total
name
: localself.name
: instancebalance
: localself.balance
: instanceinterest
: classamt
: localtotal
: local
Question 3
Consider the following code:
class Person:
def __init__(self, name):
self.name = name
Let's say we want to have a variable that keeps track of all the Person objects ever created.
- What type of variable should this be? (local, instance, or class)
- Modify the code to initialize
population
to 0, and to increment it by 1 every time you create a new Person object.
This would be a class variable. The new code would look like this:
class Person:
population = 0
def __init__(self, name):
self.name = name
Person.population += 1
Variables: What would Python print?
For the following questions, use the following class definition:
class Account:
"""A class computer account. Each account has a two-letter ID
and the name of the student who is registered to the account.
"""
num_of_accounts = 0
def __init__(self, id):
self.id = id
Account.num_of_accounts += 1
def register(self, student):
self.student = student
print('Registered!')
@property
def type(self):
return type(self)
Question 4
>>> self.id
______NameError
>>> acc_aa = Account("aa")
>>> acc_aa.id
______'aa'
>>> acc_aa.student
______AttributeError (self.student not defined yet)
>>> acc_aa.register("Peter Perfect")
______Registered!
>>> acc_aa.student
______'Peter Perfect'
>>> num_of_accounts
______NameError
>>> Account.num_of_accounts
______1
>>> acc_aa.num_of_accounts
______1
>>> acc_zz = Account("zz")
>>> Account.num_of_accounts
______2
>>> acc_aa.num_of_accounts
______2
>>> acc_zz.num_of_accounts
______2
>>> acc_aa.num_of_accounts = 100
>>> acc_aa.num_of_accounts
______100
>>> acc_zz.num_of_accounts
______2
>>> Account.num_of_accounts
______2
>>> Account.num_of_accounts = 9001
>>> acc_aa.num_of_accounts
______100
>>> acc_zz.num_of_accounts
______9001
Methods: Conceptual Questions
Question 5
Here is the same Account
class from the previous section:
class Account:
"""A class computer account. Each account has a two-letter ID
and the name of the student who is registered to the account.
"""
num_of_accounts = 0
def __init__(self, id):
self.id = id
Account.num_of_accounts += 1
def register(self, student):
self.student = student
print('Registered!')
@property
def type(self):
return type(self)
Why is it that, when I call acc_aa.register('me')
no errors will be
raised, even though I didn't pass in an argument for self
?
The dot notation will implicitly pass acc_aa
into type
as self
.
This is known as a bound method. Another way to think about it is
that acc_aa.register
acts like a curried function
>>> acc_aa.register = curry2(Account.register)(acc_aa)
>>> acc_aa.register('me')
Registered!
Question 6
Can a method have the same name as a variable?
No; in python, variables and methods share the same namespace, so variable and method names can collide if you aren't careful.
Question 7
What does the @property
decorator do?
The @property
decorator allows you to use the affected method to
be accessed like a variable. For example, the following method
>>> class Example:
... @property
... def foo(self):
... return 3""") + """can be accessed like
... this:""" + prettify("""
>>> a = Example()
>>> a.foo
3
Methods: What would Python print?
For the following questions, use the Account
class defined below:
class Account:
"""A class computer account. Each account has a two-letter ID
and the name of the student who is registered to the account.
"""
num_of_accounts = 0
def __init__(self, id):
self.id = id
Account.num_of_accounts += 1
def register(self, student):
self.student = student
print('Registered!')
@property
def type(self):
return type(self)
Question 8
>>> acc_aa = Account("aa")
>>> acc_aa.register
______<bound method Account.register ...>
>>> Account.register
______<function register at ...> # (not a bound method!)
>>> acc_aa.register(self, "Peter Perfect")
______NameError
>>> acc_aa.register("Peter Perfect")
______Registered!
>>> acc_aa.type()
______TypeError
>>> acc_aa.type
______<class '__main__.Account'>
>>> acc_aa.type = "Nothing"
______AttributeError