OOP Fundamentals
Chapter: 2.1 OOP Fundamentals Level: 2 — Recall & Standard Problems Time Limit: 30 minutes Total Marks: 40
Answer all questions. For code questions, write output exactly as Python would print it. Use
$...$conventions only where math is needed.
Q1. Define the difference between a class and an object. Give one real-world analogy. (3 marks)
Q2. What is the purpose of the __init__ method? State one fact about what it can and cannot return. (3 marks)
Q3. Consider the class below. State what A.count and a.count print, and explain the difference between instance and class attributes. (4 marks)
class A:
count = 0
def __init__(self):
A.count += 1
self.count = 100
a = A()
print(A.count)
print(a.count)Q4. Explain the difference between an instance method, a @classmethod, and a @staticmethod. State what first parameter (if any) each receives. (5 marks)
Q5. What is self in Python? Explain how Python passes it when you call obj.method(). (4 marks)
Q6. Explain name mangling. Given the code below, write the actual attribute name Python creates, and state whether print(obj.__secret) from outside the class works. (4 marks)
class Vault:
def __init__(self):
self.__secret = 42Q7. Rewrite the following so temperature is exposed as a property with a getter and a setter that rejects values below (raise ValueError). (5 marks)
class Cell:
def __init__(self, temp):
self._temp = tempQ8. Given the inheritance below, write the MRO of class C (using C.__mro__ names) and state what C().greet() prints. (4 marks)
class A:
def greet(self): return "A"
class B(A):
def greet(self): return "B"
class C(B):
passQ9. What does super() do? In the snippet below, what does Dog("Rex").describe() return? (4 marks)
class Animal:
def __init__(self, name):
self.name = name
def describe(self):
return f"Animal:{self.name}"
class Dog(Animal):
def describe(self):
return "Dog-" + super().describe()Q10. Define duck typing in one sentence, and complete the __add__ and __eq__ dunder methods for the Vec class so that Vec(1,2) + Vec(3,4) == Vec(4,6) evaluates to True. (4 marks)
class Vec:
def __init__(self, x, y):
self.x, self.y = x, y
# __add__ here
# __eq__ hereAnswer keyMark scheme & solutions
Q1. (3 marks)
- A class is a blueprint/template that defines attributes and behaviour (1)
- An object is a concrete instance of a class created in memory with its own state (1)
- Analogy: class = architectural blueprint, object = actual house built from it (also acceptable: cookie-cutter vs cookie) (1)
Q2. (3 marks)
__init__is the constructor/initializer; it runs automatically after object creation to set up initial instance attributes (2)- It must return
None— it cannot return a value other than None (returning anything else raisesTypeError) (1)
Q3. (4 marks)
A.countprints1(1) — the class attribute was incremented once in__init__a.countprints100(1) — an instance attributecountshadows the class attribute- Explanation: class attributes are shared across all instances; instance attributes belong to one object.
self.count = 100creates a new instance attribute that hides the class one for lookups ona(2)
Q4. (5 marks)
- Instance method: receives
self(the instance) as first parameter; operates on instance data (1.5) @classmethod: receivescls(the class) as first parameter; can access/modify class state; often used as alternative constructors (1.5)@staticmethod: receives no implicit first parameter; a plain function namespaced inside the class (1.5)- Correctly naming first params
self/cls/ none (0.5)
Q5. (4 marks)
selfis a reference to the current instance on which a method is called (2)- When you call
obj.method(), Python translates it toClass.method(obj)— the instance is passed automatically/implicitly as the first argument, bound toself(2)
Q6. (4 marks)
- Name mangling: any identifier of form
__name(two leading underscores, at most one trailing) inside a class is rewritten to_ClassName__name(2) - Actual attribute name:
_Vault__secret(1) print(obj.__secret)from outside fails withAttributeError, because outside the class__secretis not mangled to the real name (1)
Q7. (5 marks)
class Cell:
def __init__(self, temp):
self.temperature = temp # goes through setter
@property
def temperature(self):
return self._temp
@temperature.setter
def temperature(self, value):
if value < -273:
raise ValueError("below absolute zero")
self._temp = value@propertygetter returning_temp(1.5)@temperature.settercorrectly named (1.5)- Validation
value < -273raisingValueError(1.5) - Storing in backing attribute
_temp(0.5)
Q8. (4 marks)
- MRO:
[C, B, A, object](2) C().greet()prints/returns"B"(1) — Python searches MRO,Chas nogreet,Bdoes, soB.greetis used (1)
Q9. (4 marks)
super()returns a proxy to call parent (next-in-MRO) class methods without hardcoding the parent name (2)Dog("Rex").describe()returns"Dog-Animal:Rex"(2) —Dog.describeprepends"Dog-"then callsAnimal.describevia super, giving"Animal:Rex"
Q10. (4 marks)
- Duck typing: if an object provides the required method/interface, its actual class doesn't matter — "if it walks and quacks like a duck, treat it as a duck" (1)
- Code (3):
def __add__(self, other):
return Vec(self.x + other.x, self.y + other.y)
def __eq__(self, other):
return self.x == other.x and self.y == other.y__add__returning new Vec (1.5),__eq__comparing both components (1.5)
[
{"claim": "Q3: A.count=1, a.count=100", "code": "class A:\n count=0\n def __init__(self):\n A.count+=1\n self.count=100\na=A()\nresult = (A.count==1 and a.count==100)"},
{"claim": "Q6: mangled name is _Vault__secret", "code": "class Vault:\n def __init__(self):\n self.__secret=42\nv=Vault()\nresult = hasattr(v,'_Vault__secret') and getattr(v,'_Vault__secret')==42"},
{"claim": "Q8: MRO of C is [C,B,A,object]", "code": "class A: pass\nclass B(A): pass\nclass C(B): pass\nresult = [k.__name__ for k in C.__mro__]==['C','B','A','object']"},
{"claim": "Q9: Dog describe returns Dog-Animal:Rex", "code": "class Animal:\n def __init__(self,name): self.name=name\n def describe(self): return f'Animal:{self.name}'\nclass Dog(Animal):\n def describe(self): return 'Dog-'+super().describe()\nresult = Dog('Rex').describe()=='Dog-Animal:Rex'"},
{"claim": "Q10: Vec add and eq work", "code": "class Vec:\n def __init__(self,x,y): self.x,self.y=x,y\n def __add__(self,o): return Vec(self.x+o.x,self.y+o.y)\n def __eq__(self,o): return self.x==o.x and self.y==o.y\nresult = (Vec(1,2)+Vec(3,4)==Vec(4,6))"}
]