2.1.7 · HinglishOOP Fundamentals

Properties — `@property`, `@setter`, `@deleter` for controlled access

1,689 words8 min readRead in English

2.1.7 · Coding › OOP Fundamentals


Properties kyun exist karti hain?

Attribute ko directly expose kyun nahi karte? Kyunki tab koi bhi rok nahi hai koi likhe account.balance = -9999. Tum apne invariants kho dete ho (woh rules jo hamesha hold hone chahiye).

Sirf get_x()/set_x() methods kyun nahi use karte? Kyunki tab har call site ko likhna padta hai obj.get_x(). Agar tumne obj.x se shuru kiya tha, toh switch karne se woh saara code toot jaata hai. Properties tumhe clean obj.x syntax bhi rakhne deti hain aur control bhi milta hai.


Property mechanically KIYA hoti hai?

Decorators sirf sugar hain:

class C:
    @property
    def x(self):          # this is property(x).fget
        return self._x
    @x.setter
    def x(self, value):   # returns a NEW property with fset filled in
        self._x = value
    @x.deleter
    def x(self):          # fills in fdel
        del self._x

Python obj.x ko kaise resolve karta hai (derivation)

Jab tum obj.x access karte ho, Python sirf obj.__dict__ mein nahi dekhta. Attribute lookup descriptor protocol follow karta hai:

  1. type(obj).__mro__ mein naam x dhundho.
  2. Agar mila AUR yeh ek data descriptor hai (defines __set__ ya __delete__) → x.__get__(obj, type(obj)) call karo. Yeh instance __dict__ se jeetta hai.
  3. Warna obj.__dict__['x'] check karo.
  4. Warna agar ek non-data descriptor (sirf __get__) mila tha → use karo.
  5. Warna AttributeError.
Figure — Properties — `@property`, `@setter`, `@deleter` for controlled access

Worked Example 1 — Validation (Temperature)

class Temperature:
    def __init__(self, celsius):
        self.celsius = celsius          # goes THROUGH the setter ✔
 
    @property
    def celsius(self):
        return self._celsius
 
    @celsius.setter
    def celsius(self, value):
        if value < -273.15:
            raise ValueError("below absolute zero")
        self._celsius = value
 
    @property
    def fahrenheit(self):               # computed, read-only
        return self._celsius * 9/5 + 32
Step Code Yeh step kyun?
1 self.celsius = celsius in __init__ Construction ke time bhi property use karo, taaki validation birth se hi chale.
2 store in self._celsius Backing field ek alag naam (_celsius) use karta hai taaki setter khud ko hamesha ke liye call na kare.
3 fahrenheit ka koi setter nahi Read-only computed value — celsius se derive hoti hai, isliye ise directly set karna ambiguous hoga.
t = Temperature(25)
t.fahrenheit      # 77.0  (computed, no stored field)
t.celsius = -300  # ValueError

Worked Example 2 — Read-only + deleter (Account)

class Account:
    def __init__(self, balance):
        self._balance = balance
 
    @property
    def balance(self):
        return self._balance            # no setter ⇒ can't reassign
 
    @balance.deleter
    def balance(self):
        print("closing account")
        self._balance = 0
Step Code Yeh step kyun?
1 koi @balance.setter define nahi acc.balance = 5 ko AttributeError raise karwa deta hai → balance sirf deposit/withdraw methods se change ho sakta hai.
2 @balance.deleter 0 par reset karta hai del acc.balance ek controlled "close" action ban jaata hai, memory wipe nahi.
acc = Account(100)
acc.balance        # 100
acc.balance = 50   # AttributeError: can't set attribute
del acc.balance    # prints "closing account", balance -> 0

Worked Example 3 — Lazy / cached computation

class Circle:
    def __init__(self, r):
        self._r = r
        self._area = None
 
    @property
    def area(self):
        if self._area is None:          # compute once, then cache
            print("computing...")
            self._area = 3.141592653589793 * self._r ** 2
        return self._area
 
    @property
    def radius(self):
        return self._r
 
    @radius.setter
    def radius(self, v):
        self._r = v
        self._area = None               # invalidate cache!

Yeh step kyun? radius set karne par _area reset hona chahiye, warna area ek stale cached value return karta hai. Properties tumhe derived data ko consistent rakhne ka hook deti hain.


Recall Feynman: ek 12-saal ke bachche ko samjhao

Socho ek vending machine hai jisme "Money" likha ek slot hai. Bahar se yeh ek simple slot lagta hai — tum bas paisa daalo. Lekin andar, ek chota guard check karta hai: kya yeh asli sikka hai? kafi paisa hai? Agar nahi, toh woh wapas de deta hai. Property wahi guard hai. Bahar se machine.money = 5 lagta hai jaise slot mein sikka daala, lekin ek hidden checker (setter) decide karta hai ki accept karna hai ya nahi. Ek read-only property woh slot hai jisme tum sirf dekh sakte ho andar kya hai (@property) lekin guard tumhe kuch push karne nahi deta (koi @setter nahi).


Flashcards

@property ek method ko kiya banata hai?
Ek read-accessor jo obj.x ko method run karwaata hai jabki plain attribute access jaisa lagta hai.
Ek setter ke andar self.x ki jagah self._x mein data kyun store karte hain?
self.x assign karne se setter phir se trigger hota → infinite recursion; _x ek alag backing field hai.
Kaunsi error raise hoti hai obj.x = v se jab sirf @property define ho (koi setter nahi)?
AttributeError: can't set attribute / property has no setter.
Property x mein setter add karne ka syntax kiya hai?
@x.setter ek method named x ke upar (same naam).
Property ek instance __dict__ entry ko same naam se kyun override karti hai?
Yeh ek data descriptor hai (defines __set__), isliye descriptor lookup instance dict se jeett jaata hai.
@x.deleter kiya control karta hai?
del obj.x par kiya hota hai — tumhe attribute ko blindly remove karne ki jagah cleanly cleanup karne deta hai.
Kaunsa principle kehta hai ki callers ko yeh nahi pata hona chahiye ki obj.x stored hai ya computed?
The Uniform Access Principle.
Property ke saath cache karte waqt, source value ke setter ko kiya karna chahiye?
Cache invalidate karo (cached field ko None par reset karo) taaki derived values stale na hon.
Kiya ek read-only property ki underlying value immutable hai?
Nahi — sirf bahari reassignment block hoti hai; internal methods phir bhi _x change kar sakti hain.
Ek property kaun se teen functions rakh sakti hai?
fget, fset, fdel (get, set, delete).

Connections

  • Encapsulation and Access Modifiers — properties Python ke "hum sab adults hain" tarike se encapsulation enforce karti hain.
  • Descriptors __get__ __set__ __delete__ — lower-level mechanism jis par property bana hai.
  • Getters and Setters in Java vs Python — same goal, cleaner syntax.
  • functools.cached_property — built-in caching property.
  • Class vs Instance Attributes — property class par rehti hai; backing field instance par.
  • Invariants and Class Design — setters mein validation object state kyun protect karta hai.

Concept Map

motivates

is a

builds

accumulate into

defines __set__

defines __delete__

intercepts

is data descriptor so

validates to keep

Uniform Access Principle

property object

Data descriptor

Decorator sugar

fget - @property

fset - @setter

fdel - @deleter

obj.x lookup

Wins over instance __dict__

Preserves invariants