Python Polymorphism MCQs (25)
Python Training in Vizag (Softenant)1) Overriding chooses subclass method
class A:
def speak(self): return "A"
class B(A):
def speak(self): return "B"
print(A().speak(), B().speak())
A. B B
B. A A
C. A B
D. Error
2) Duck typing works without inheritance
def say(x): return x.speak()
class Dog: def speak(self): return "woof"
class Cat: def speak(self): return "meow"
print(say(Dog()), say(Cat()))
A. woof meow
B. Error
C. Dog Cat
D. None None
3) Polymorphic __str__
class A:
def __str__(self): return "A"
class B(A):
def __str__(self): return "B"
print(str(A()), str(B()))
A. A A
B. B B
C. A B
D. object object
4) Same interface, different results
class S:
def area(self): return 1
class R(S):
def area(self): return 6
for s in (S(), R()):
print(s.area(), end=" ")
A. 6 1
B. 1 6
C. 1 1
D. (no output)
5) Operator overloading (__add__)
class V:
def __init__(self,x): self.x=x
def __add__(self,o): return V(self.x + o.x)
print( (V(2)+V(3)).x )
A. 23
B. 5
C. V(5)
D. Error
6) Reflected add (__radd__)
class V:
def __init__(self,x): self.x=x
def __radd__(self,o): return self.x + o
print(10 + V(5))
A. 15
B. 105
C. TypeError
D. V(15)
7) Builtins use protocols (len → __len__)
class Bag:
def __len__(self): return 3
print(len(Bag()))
A. 0
B. 3
C. True
D. TypeError
8) Iterable protocol (__iter__)
class C:
def __iter__(self): return iter([1,2,3])
print(sum(C()))
A. 0
B. 6
C. TypeError
[1,2,3]
9) Membership via __contains__
class K:
def __contains__(self, item): return item == "x"
print("x" in K(), "y" in K())
A. True False
B. False True
C. True True
D. False False
10) functools.singledispatch polymorphism
from functools import singledispatch
@singledispatch
def f(x): return "base"
@f.register(int)
def _(x): return "int"
print(f(1), f("a"))
A. int base
B. base int
C. int int
D. Error Error
11) MRO decides which method
class X:
def f(self): return "X"
class Y:
def f(self): return "Y"
class Z(Y, X): pass
print(Z().f())
A. X
B. Y
C. XY
D. Error
12) Using super() to extend behavior
class A:
def f(self): return "A"
class B(A):
def f(self): return super().f() + "B"
print(B().f())
A. B
B. AB
C. A
D. BA
13) Subclass instances are also base instances
class A: pass
class B(A): pass
print(isinstance(B(), A), issubclass(B, A))
A. True True
B. True False
C. False True
D. False False
14) EAFP duck typing
def draw(obj):
try: return obj.draw()
except AttributeError: return "no"
class P:
def draw(self): return "p"
print(draw(P()), draw(object()))
A. p no
B. no p
C. Error Error
D. p p
15) Polymorphic builtins (len over many types)
print(list(map(len, ["a", (1,2), {3,4}])))
A. [1, 2, 2]
B. [1, 2, 1]
C. [1, 2, 0]
D. TypeError
16) Value-based equality (__eq__)
class P:
def __init__(self,x): self.x=x
def __eq__(self,o): return isinstance(o,P) and self.x==o.x
print(P(1)==P(1), P(1)==P(2))
A. True True
B. True False
C. False True
D. False False
17) Ordering via __lt__
class W:
def __init__(self,x): self.x=x
def __lt__(self,o): return self.x < o.x
print([w.x for w in sorted([W(3), W(1)])])
A. [3, 1]
B. [1, 3]
C. [1]
D. Error
18) Callable objects (__call__)
class F:
def __call__(self,x): return x*2
f = F()
print(f(3))
A. 6
B. 3
C. TypeError
D. None
19) Context manager protocol
class R:
def __enter__(self): return "ok"
def __exit__(self, *a): pass
with R() as v:
print(v)
A. ok
B. True
C. None
D. Error
20) Iterator protocol
class It:
def __iter__(self): self.i=0; return self
def __next__(self):
self.i += 1
if self.i <= 2: return self.i
raise StopIteration
print(list(It()))
A. [1, 2]
B. [0, 1]
C. []
D. Error
21) Dynamic attribute via __getattr__
class D:
def __getattr__(self, name): return 42
d = D()
print(d.foo)
A. 42
B. AttributeError
C. None
D. foo
22) Overloading matrix-multiply (__matmul__)
class M:
def __matmul__(self, o): return "matmul"
print(M() @ M())
A. matmul
B. @
C. TypeError
D. None
23) Truthiness via __len__/__bool__
class B:
def __len__(self): return 0
print(bool(B()))
A. True
B. False
C. 0
D. Raises
24) File-like duck type
def write_all(f): f.write("hi")
class S:
def __init__(self): self.buf=""
def write(self, s): self.buf += s
s = S(); write_all(s)
print(s.buf)
A. hi
B. ''
C. None
D. TypeError
25) Return types can vary across overrides
class A:
def f(self): return 1
class B(A):
def f(self): return "x"
print(type(A().f()).__name__, type(B().f()).__name__)
A. int str
B. str int
C. int int
D. Error
Answer Key
1) C
2) A
3) C
4) B
5) B
6) A
7) B
8) B
9) A
10) A
11) B
12) B
13) A
14) A
15) A
16) B
17) B
18) A
19) A
20) A
21) A
22) A
23) B
24) A
25) A