You’re the Expert!

pynfinity

Build mountain with each pebble 🧗

Topics | Stepping Stones

📚 Guides

🌍 Pebbles & Contributions

✍️ Write a Post
🐼 Pandas DataFrames
🐼 Pandas DataFrames
🔢 NumPy Arrays
🔢 NumPy Arrays
📉 Matplotlib Plotting
📉 Matplotlib Plotting
🔥 Seaborn Heatmaps
🔥 Seaborn Heatmaps
🤖 Scikit-Learn Linear Regression
🤖 Scikit-Learn Linear Regression
🧹 Data Cleaning with Dropna
🧹 Data Cleaning with Dropna
🔍 Exploratory Data Analysis (EDA)
🔍 Exploratory Data Analysis (EDA)
⏳ Time Series Resampling
⏳ Time Series Resampling
🕸️ Web Scraping with BeautifulSoup
🕸️ Web Scraping with BeautifulSoup
🗄️ SQLAlchemy Basics
🗄️ SQLAlchemy Basics
📊 Interactive Plots with Plotly
📊 Interactive Plots with Plotly
📝 NLTK Tokenization
📝 NLTK Tokenization
🧠 TensorFlow Basics
🧠 TensorFlow Basics
🔥 PyTorch Tensors
🔥 PyTorch Tensors
📉 Statsmodels OLS
📉 Statsmodels OLS
📸 OpenCV Image Reading
📸 OpenCV Image Reading
🕸️ NetworkX Graphs
🕸️ NetworkX Graphs
🗺️ Folium Maps
🗺️ Folium Maps
🚀 Streamlit Apps
🚀 Streamlit Apps
⚡ FastAPI Endpoints
⚡ FastAPI Endpoints
✨ Jupyter Magic Commands
✨ Jupyter Magic Commands
📦 Virtual Environments
📦 Virtual Environments
🌲 Git Basics
🌲 Git Basics
🐳 Dockerfiles
🐳 Dockerfiles
☁️ AWS S3 with Boto3
☁️ AWS S3 with Boto3
🧩 Regular Expressions
🧩 Regular Expressions
λ Lambda Functions
λ Lambda Functions
📜 List Comprehensions
📜 List Comprehensions
⚡ Generators
⚡ Generators
🎀 Decorators
🎀 Decorators
🚪 Context Managers
🚪 Context Managers
🧵 Multithreading
🧵 Multithreading
🎛️ Multiprocessing
🎛️ Multiprocessing
⏳ AsyncIO
⏳ AsyncIO
🏷️ Type Hinting
🏷️ Type Hinting
📦 Dataclasses
📦 Dataclasses
🛡️ Pydantic Models
🛡️ Pydantic Models
🧪 Pytest Testing
🧪 Pytest Testing
🪵 Logging
🪵 Logging
💻 Argparse CLI
💻 Argparse CLI
📄 JSON Handling
📄 JSON Handling
📊 CSV Processing
📊 CSV Processing
🥒 Pickle Serialization
🥒 Pickle Serialization
🖥️ OS Module
🖥️ OS Module
⚙️ Sys Module
⚙️ Sys Module
📚 Collections Module
📚 Collections Module
🔁 Itertools
🔁 Itertools
🛠️ Functools
🛠️ Functools
➗ Math Module
➗ Math Module
+ New Post

🏷 Descriptors in Python

Descriptors are the mechanism behind properties, methods, static methods, class methods, and super(). They are objects that define how attribute access is handled.


🧠 What is a Descriptor?

A descriptor is any object that defines at least one of the following methods:
- __get__(self, obj, type=None)
- __set__(self, obj, value)
- __delete__(self, obj)

If an object defines these, it is considered a descriptor.


🛠 Creating a Descriptor

Let's create a descriptor that enforces type checking.

class Integer:
    def __init__(self, name):
        self.name = name

    def __get__(self, instance, owner):
        if instance is None:
            return self
        return instance.__dict__.get(self.name)

    def __set__(self, instance, value):
        if not isinstance(value, int):
            raise TypeError(f"{self.name} must be an integer")
        instance.__dict__[self.name] = value

class Point:
    x = Integer('x')
    y = Integer('y')

    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(1, 2)
p.x = 5  # OK
# p.y = "hello"  # Raises TypeError

🏷 __set_name__

In Python 3.6+, __set_name__ allows the descriptor to know the name of the attribute it is assigned to.

class Integer:
    def __set_name__(self, owner, name):
        self.name = name

    def __get__(self, instance, owner):
        return instance.__dict__.get(self.name)

    def __set__(self, instance, value):
        if not isinstance(value, int):
            raise TypeError(f"{self.name} must be an integer")
        instance.__dict__[self.name] = value

class Point:
    x = Integer() # No need to pass 'x'
    y = Integer()

🧩 Data vs Non-Data Descriptors

  • Data Descriptor: Defines __set__ or __delete__. Always overrides the instance dictionary.
  • Non-Data Descriptor: Only defines __get__ (like methods). Can be overridden by the instance dictionary.

📝 Summary

  • Under the Hood: Powering many Python features like @property.
  • Reusable Logic: Encapsulate attribute access logic (validation, lazy loading).
  • Control: Fine-grained control over attribute access.

Created with ❤️ by Pynfinity