Softenant
Technologies
Python Abstraction

Python Abstraction (ABCs & Protocols) MCQs (25)

Python Training in Vizag (Softenant)

1) Instantiating an ABC with unimplemented abstract method

from abc import ABC, abstractmethod
class Shape(ABC):
    @abstractmethod
    def area(self): ...
class Rect(Shape): pass
Rect()
A. Works
B. TypeError
C. AttributeError
D. Prints 0

2) Implement and instantiate

class Rect(Shape):
    def area(self): return 6
print(isinstance(Rect(), Shape))
A. True
B. False
C. TypeError
D. None

3) Abstract method with body is still abstract

class A(ABC):
    @abstractmethod
    def f(self):
        return 1
class B(A): pass
B()
A. Works (returns 1)
B. TypeError
C. 1
D. None

4) Concrete methods inside ABC

class Base(ABC):
    def greet(self): return "hi"
print(Base.greet(Base))
A. hi
B. TypeError
C. None
D. AttributeError

5) Abstract property must be implemented

class A(ABC):
    @property
    @abstractmethod
    def x(self): ...
class B(A):
    @property
    def x(self): return 2
print(B().x)
A. 2
B. TypeError
C. AttributeError
D. None

6) Partial implementation still abstract

class A(ABC):
    @abstractmethod
    def f(self): ...
    @abstractmethod
    def g(self): ...
class B(A):
    def f(self): return 1
B()
A. Works
B. TypeError
C. Returns 1
D. Prints 1

7) Abstract classmethod

class A(ABC):
    @classmethod
    @abstractmethod
    def name(cls): ...
class B(A):
    @classmethod
    def name(cls): return "B"
print(B.name())
A. B
B. TypeError
C. None
D. name

8) Abstract staticmethod

class A(ABC):
    @staticmethod
    @abstractmethod
    def v(): ...
class B(A):
    @staticmethod
    def v(): return 3
print(B.v())
A. 3
B. TypeError
C. None
D. v

9) Abstract property with setter

class A(ABC):
    @property
    @abstractmethod
    def x(self): ...
    @x.setter
    @abstractmethod
    def x(self, val): ...
class B(A):
    def __init__(self): self._x=0
    @property
    def x(self): return self._x
    @x.setter
    def x(self, val): self._x=val
b = B(); b.x = 5; print(b.x)
A. 5
B. TypeError
C. AttributeError
D. None

10) Virtual subclass via register

class S(ABC): pass
class Foo: pass
S.register(Foo)
print(isinstance(Foo(), S))
A. True
B. False
C. TypeError
D. Depends on Foo

11) Register doesn’t add methods

class A(ABC):
    @abstractmethod
    def f(self): ...
class T: pass
A.register(T)
print(hasattr(T(), "f"))
A. True
B. False
C. TypeError
D. AttributeError

12) issubclass with register

print(issubclass(T, A))
A. True
B. False
TypeError
D. None

13) Protocol (structural typing)

from typing import Protocol
class Quacker(Protocol):
    def quack(self) -> str: ...
class Duck:
    def quack(self) -> str: return "quack"
def speak(q: Quacker) -> str: return q.quack()
print(speak(Duck()))
A. quack
B. TypeError
C. Protocol
D. None

14) Protocol doesn’t enforce at runtime (no check)

class Stone: pass
print(isinstance(Stone(), Quacker))
A. Always True
B. False (normal runtime)
C. TypeError
D. Depends on mypy

15) ABC with concrete helper + abstract core

class Base(ABC):
    def twice(self): return self.core()*2
    @abstractmethod
    def core(self): ...
class C(Base):
    def core(self): return 3
print(C().twice())
A. 6
B. 3
C. TypeError
D. None

16) Abstract class can’t be instantiated even with concrete methods

class Z(ABC):
    def ok(self): return 1
    @abstractmethod
    def need(self): ...
Z()
A. Works
B. TypeError
1
D. None

17) Implementing abstractmethod in subclass

class Z1(Z):
    def need(self): return "done"
print(Z1().ok(), Z1().need())
A. 1 done
B. TypeError
C. done 1
D. None None

18) Abstractmethod on property + override to concrete attribute (not allowed)

class A(ABC):
    @property
    @abstractmethod
    def name(self): ...
class B(A):
    name = "B"
B()
A. Works
B. TypeError (still abstract)
C. AttributeError
D. None

19) isinstance with ABC vs Protocol

print(isinstance(Duck(), Quacker), isinstance(Duck(), A))
A. True False
B. True True
C. False True
False False

20) Combining ABC with concrete __init__

class S(ABC):
    def __init__(self, x): self.x = x
    @abstractmethod
    def area(self): ...
class Sq(S):
    def area(self): return self.x * self.x
print(Sq(3).area())
A. 9
B. TypeError
C. 3
D. None

21) Abstractmethod on dunder methods is valid

class Cmp(ABC):
    @abstractmethod
    def __lt__(self, other): ...
class K(Cmp):
    def __lt__(self, o): return False
print(isinstance(K(), Cmp))
A. True
B. False
TypeError
D. None

22) Using ABC to standardize interface

class Repo(ABC):
    @abstractmethod
    def save(self, obj): ...
class MemoryRepo(Repo):
    def save(self, obj): return "ok"
def persist(r: Repo): return r.save(1)
print(persist(MemoryRepo()))
A. ok
B. TypeError
C. Repo
D. None

23) Protocol with optional members (via @runtime_checkable)

from typing import Protocol, runtime_checkable
@runtime_checkable
class P(Protocol):
    def ping(self) -> str: ...
class X:
    def ping(self) -> str: return "pong"
print(isinstance(X(), P))
A. True
B. False
TypeError
D. None

24) Abstract dataclass fields

from dataclasses import dataclass
@dataclass
class BBase(ABC):
    @abstractmethod
    def build(self): ...
class Impl(BBase):
    def build(self): return 1
print(Impl().build())
A. 1
B. TypeError
None
D. build

25) Common pitfall: forgetting to implement all abstracts

class A(ABC):
    @abstractmethod
    def a(self): ...
    @abstractmethod
    def b(self): ...
class B(A):
    def a(self): return 1
print(issubclass(B, A))
A. True (and B() works)
B. True (but B() raises TypeError)
C. False
D. NameError

Answer Key

1) B

2) A

3) B

4) A

5) A

6) B

7) A

8) A

9) A

10) A

11) B

12) A

13) A

14) B

15) A

16) B

17) A

18) B

19) A

20) A

21) A

22) A

23) A

24) A

25) B