Descriptor: A descriptor is a special object in Python that lets you control what happens when you get, set, or delete an attribute on a class.
All in all they helps us to customize attribute access and behavior
e.g.
__get__(self, obj, objtype=None)
__set__(self, obj, value)
__delete__(self, obj)
__get_name__
Descriptors are the core behind:
@property
@staticmethod
@classmethod
and any custom attribute access logic!
There are two types of Descriptors
- Non-data Descriptors
class Q: def __get__(self, instance, owner): return "Yes" class P: attr = Q() p = P() print(p.attr) # Output: Yes
- Data Descriptors
class X: def __get__(self, obj, objcls): print(f"Getting value from {obj=} of type {objcls=}") if obj: return getattr(obj, "_find_x", "Nothing here") return getattr(objcls, "_find_x", "Nothing here") def __set__(self, obj, value): print(f"Setting {value=} on {obj=}") setattr(obj, "_find_x", value) def __delete__(self, obj): print(f"Deleting {obj} from find_x") delattr(obj, "_find_x") class P: attr = X() def __init__(self, value): self.attr = value print(P.attr) # Output: Getting value from obj=None of type objcls=<class '__main__.P'> # Nothing here p = P(15) # Output: Setting value=15 on obj=<__main__.P object at 0x7e8eaded1d00> print(p.attr) # Output: Getting value from obj=<__main__.P object at 0x7e8eaded1d00> of type objcls=<class '__main__.P'> # 15 print(p.__dict__) # {'_find_x': 15} print(del p.attr) # Output: Deleting <__main__.P object at 0x7d4a4bcd5d00> from find_x
Bonus:
__dict__
: It basically tells the attributes of the class in dictionary format.
It has two types:
- Class Attributes: Attributes defined directly within a class are stored in class's
__dict__
.
class Q: a = 98 q = Q() print(q.__dict__) # Output: {} print(q.a) # Output: 98 print(Q.__dict__) # Output: {..., 'a': 98, ...other attributes}
- Instance Attributes: Each instance has its own
__dict__
that stores attributes unique to that instance.
class Q: def __init__(self): self.a = 98 q = Q() print(q.__dict__) # Output: {'a': 98} q.x = 23 print(q.__dict__) # Output: {'a': 98, 'x': 23} print(Q.__dict__) # Output: {<will not contain a or x>}
Top comments (0)