Python
OOP: Properties, Methods & Data Classes
39 flashcards · answers and spaced-repetition review in the KnowCard app
What does this print?
```
class C:
@property
def area(self):
return self.w * self.h
c = C(); c.w, c.h = 3, 4
print(c.area)
print(c.area())
```
You expose a public attribute obj.temp and ship it. Later you need to reject negative values on write. Why is starting with @property from day one the safer call?
A class has @property def x with only a getter. What happens at obj.x = 5?
What does this print?
```
class A:
@staticmethod
def add(a, b):
return a + b
print(A.add(2, 3))
print(A().add(2, 3))
```
What is printed?
```
class A:
@classmethod
def who(cls):
return cls.__name__
class B(A): pass
print(A.who(), B.who())
```
You want Date.from_string("2026-06-27") to build and return a Date instance (an alternative constructor). Which method kind, and what's the key line in the body?
self / cls / nothing: which implicit first parameter does each receive — an instance method, a @classmethod, and a @staticmethod?
What does this print?
```
class Dog:
tricks = []
def add(self, t):
self.tricks.append(t)
a, b = Dog(), Dog()
a.add("sit"); b.add("roll")
print(a.tricks)
```
What does this print?
```
class C:
x = 10
p = C(); q = C()
p.x = 99
print(q.x, C.x)
```
What does this print?
```
class A:
def __init__(self):
self.x = 42
a = A()
print(a.__dict__)
print("y" in a.__dict__)
```
What does this print?
```
class A:
def __init__(self):
self.x = 1
a = A()
print(getattr(a, "x"))
print(getattr(a, "y", 99))
print(getattr(a, "y"))
```
Code does if obj.config: ... but config may be unset, risking AttributeError. Compare the two guards: hasattr(obj, "config") vs getattr(obj, "config", None).
What does vars(obj) return, and how does it relate to obj.__dict__?
What does this print?
```
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
print(Point(1, 2) == Point(1, 2))
print(Point(1, 2))
```
What does this print?
```
from dataclasses import dataclass
@dataclass
class Bag:
tags: list = []
```
What does this print?
```
@dataclass
class Bag:
xs: list = field(
default_factory=list)
a = Bag(); b = Bag()
a.xs.append(1)
print(b.xs)
```
What does this print?
```
from dataclasses import dataclass
@dataclass(frozen=True)
class P:
x: int
p = P(1)
p.x = 2
```
Why add @dataclass over a hand-written class or a collections.namedtuple for a structured record you need to mutate?
What does this print?
```
class B:
__slots__ = ("x", "y")
def __init__(self):
self.x = 1
b = B()
b.y = 2
b.z = 3
```
What does this print?
```
class B:
__slots__ = ("x",)
def __init__(self):
self.x = 1
b = B()
print(b.__dict__)
```
What does this print?
```
class A:
@classmethod
def make(cls):
return cls()
class B(A): pass
print(type(B.make()).__name__)
```
What does this print?
```
class SortedList(list):
def append(self, v):
super().append(v)
self.sort()
l = SortedList([3, 1, 2])
print(l)
l.append(0)
print(l)
```
Which magic methods make -obj, abs(obj), and ~obj work on your class?
What does this print?
from dataclasses import dataclass
@dataclass
class P:
x: int
print(P("hello").x)
Can a @dataclass have regular methods and act as a base or subclass, or is it only a passive data holder?
A @dataclass auto-generates __init__, so where do you put validation or derive one field from the others?
Another module does obj._balance = -50 on your class's underscored attribute. Does Python stop it?
You built a Money class that acts like a number. Beyond arithmetic operators, which methods let int(m), float(m), round(m), and using it as a list index work?
You write 3 * money where money is your class. (3).__mul__(money) has no idea what money is. How does Python still let your class handle it?
By default x += 5 does what under the hood, and what changes once you define __iadd__?
Besides the @property decorator, how do you build a property by calling property() directly, and what does its third argument do?
You wrap a hot, frequently-read attribute in a @property getter. What's the runtime tradeoff versus a plain attribute?
What does this print?
class P:
def __init__(self, n):
self.n = n
print(P(5) == P(5))
In __eq__ or __add__, when other is a type you can't handle, why return NotImplemented instead of raising or returning False?
Your class defines __len__, __getitem__, and __iter__ but does NOT inherit from list. Code that expects a sequence still works on it. What principle is this?
Sorting your objects with sorted() raises TypeError: '<' not supported. Which magic method fixes it, and what are the six comparison hooks?
To make vec_a + vec_b and vec_a * 3 work on your own class, which magic methods do you implement, and what must they return?
When emulating a container, what's the defining difference between a sequential container and a mapping container?
Which magic methods must your custom container define so that len(c), c[k], c[k] = v, del c[k], for x in c, and x in c all work?
Start learning today
Free to start — download the app or use it in your browser.
