Python Encapsulation MCQs (25)
Python Training in Vizag (Softenant)1) Public attribute access
class P:
def __init__(self): self.name = "Ana"
print(P().name)
A. Ana
B. AttributeError
C. None
D. name
2) Single underscore is a convention
class C:
def __init__(self): self._x = 1
c = C(); print(c._x)
A. 1
B. AttributeError
C. None
D. _x
3) Double underscore ⇒ name mangling
class C:
def __init__(self): self.__x = 7
c = C()
print(hasattr(c, "__x"), hasattr(c, "_C__x"))
A. True True
B. False True
C. True False
D. False False
4) Accessing a mangled name
class K:
def __init__(self): self.__secret = 42
k = K()
print(k._K__secret)
A. 42
B. AttributeError
C. None
D. _K__secret
5) Private names don’t override across subclasses
class A:
def __init__(self): self.__x = "A"
class B(A):
def __init__(self):
super().__init__(); self.__x = "B"
b = B()
print(b._A__x, b._B__x)
A. A B
B. B B
C. A A
AttributeError
6) Read-only property
class A:
def __init__(self): self._x = 2
@property
def x(self): return self._x
a = A(); print(a.x)
A. 2
B. AttributeError
C. None
D. x
7) Setting a read-only property
class A:
@property
def x(self): return 1
a = A()
try:
a.x = 10
except Exception as e:
print(type(e).__name__)
A. AttributeError
B. TypeError
C. ValueError
D. No output
8) Read–write property with validation
class A:
def __init__(self): self._age = 0
@property
def age(self): return self._age
@age.setter
def age(self, v):
if v < 0: raise ValueError("age")
self._age = v
a = A(); a.age = 5; print(a.age)
A. 5
B. 0
C. ValueError
D. None
9) Deleter
class A:
def __init__(self): self._x = 9
@property
def x(self): return self._x
@x.deleter
def x(self): del self._x
a = A(); del a.x
print(hasattr(a, "_x"))
A. False
B. True
C. AttributeError
None
10) Encapsulation pitfall: exposing mutable internals
class Box:
def __init__(self): self._data = [1, 2]
@property
def data(self): return self._data # exposes internals
b = Box(); out = b.data; out.append(3)
print(b._data)
A. [1, 2]
B. [1, 2, 3]
C. []
D. AttributeError
11) Defensive copy for safety
class SafeBox:
def __init__(self): self._data = [1, 2]
@property
def data(self): return tuple(self._data)
s = SafeBox(); out = list(s.data); out.append(3)
print(s._data)
A. [1, 2, 3]
B. [1, 2]
C. ()
D. AttributeError
12) Module export convention
(Concept)A. Names starting with
_ are excluded by from m import * by defaultB. They are always imported
C. Python forbids leading underscores
D. Underscores delete variables
13) __all__ controls star-import
# m.py
__all__ = ["public"]
public = 1
_hidden = 2
A. Only
public is imported via from m import *B. Both are imported
C. None are imported
D. Only
_hidden14) __slots__ blocks new attributes
class P:
__slots__ = ("x",)
p = P(); p.x = 1
try:
p.y = 2
except Exception as e:
print(type(e).__name__)
A. AttributeError
B. TypeError
C. No output
D. KeyError
15) Frozen dataclass is immutable
from dataclasses import dataclass
@dataclass(frozen=True)
class Point: x:int; y:int
p = Point(1,2)
try:
p.x = 9
except Exception as e:
print(type(e).__name__)
A. FrozenInstanceError
B. AttributeError
C. TypeError
D. No output
16) Descriptor for validated attribute
class Positive:
def __set_name__(self, owner, name): self.name = name
def __get__(self, obj, objtype=None): return obj.__dict__[self.name]
def __set__(self, obj, val):
if val <= 0: raise ValueError("positive")
obj.__dict__[self.name] = val
class Account:
balance = Positive()
a = Account(); a.balance = 10
print(a.balance)
A. 10
B. ValueError
C. None
D. AttributeError
17) Blocking attribute via __setattr__
class Guard:
def __setattr__(self, k, v):
if k == "token": raise ValueError("no")
super().__setattr__(k, v)
g = Guard()
try:
g.token = "abc"
except Exception as e:
print(type(e).__name__)
A. ValueError
B. AttributeError
C. TypeError
D. No output
18) Intercept reads via __getattribute__
class Hide:
def __getattribute__(self, name):
if name == "_secret": raise AttributeError("hidden")
return super().__getattribute__(name)
def __init__(self): object.__setattr__(self, "_secret", 1); self.x = 2
h = Hide()
print(hasattr(h, "_secret"), h.x)
A. False 2
B. True 2
C. AttributeError
D. None 2
19) Class-level mutable leaks across instances
class Bag:
items = []
def add(self, x): self.items.append(x)
a = Bag(); b = Bag()
a.add(1)
print(b.items)
A. []
B. [1]
C. AttributeError
D. None
20) Fix leak with per-instance state
class Bag:
def __init__(self): self.items = []
a = Bag(); b = Bag()
a.items.append(1)
print(b.items)
A. [1]
B. []
C. None
D. AttributeError
21) Hiding helper via name-mangled method
class T:
def __helper(self): return "h"
def call(self): return self.__helper()
t = T(); print(t.call(), hasattr(t, "__helper"))
A. h False
B. h True
C. AttributeError False
D. helper False
22) Accessing the mangled method directly
print(hasattr(t, "_T__helper"))
A. True
B. False
C. AttributeError
D. None
23) Returning copies in getters
class Conf:
def __init__(self, d): self._d = dict(d)
@property
def data(self): return self._d.copy()
c = Conf({"a":1}); got = c.data; got["a"] = 9
print(c._d["a"])
A. 1
B. 9
C. KeyError
D. None
24) Encapsulating validation through property
class Temp:
def __init__(self): self._c = 0
@property
def celsius(self): return self._c
@celsius.setter
def celsius(self, v):
if v < -273.15: raise ValueError("below absolute zero")
self._c = v
t = Temp()
try:
t.celsius = -300
except Exception as e:
print(type(e).__name__)
A. ValueError
B. AttributeError
C. TypeError
D. No output
25) Don’t rely on privacy for security
(Concept)A. Name mangling is an access-control mechanism that prevents all access
B. Name mangling is a convention that discourages accidental access
C. Underscores encrypt values
D. Properties make data unchangeable always
Answer Key
1) A
2) A
3) B
4) A
5) A
6) A
7) A
8) A
9) A
10) B
11) B
12) A
13) A
14) A
15) A
16) A
17) A
18) A
19) B
20) B
21) A
22) A
23) A
24) A
25) B