Softenant
Technologies
Python Polymorphism MCQs (25) — Answers at the End

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