DEV Community

Customizing Lyf
Customizing Lyf

Posted on

Descriptor in Python


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

  1. Non-data Descriptors
class Q: def __get__(self, instance, owner): return "Yes" class P: attr = Q() p = P() print(p.attr) # Output: Yes 
Enter fullscreen mode Exit fullscreen mode
  1. 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 
Enter fullscreen mode Exit fullscreen mode

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} 
Enter fullscreen mode Exit fullscreen mode
  • 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>} 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)