GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Python Technologies
  • Databases
  • Computer Programming
  • Web Development
  • Java Technologies
  • Computer Science
  • Mobile Development
  • Big Data & Analytics
  • Microsoft Technologies
  • DevOps
  • Latest Technologies
  • Machine Learning
  • Digital Marketing
  • Software Quality

This view

  • Original page
  • New address

GeezerVison is showing www.tutorialspoint.com — Python - Descriptors

Python Tutorial
  • Python - Home
  • Python - Overview
  • Python - History
  • Python - Features
  • Python vs C++
  • Python - Hello World Program
  • Python - Application Areas
  • Python - Interpreter
  • Python - Environment Setup
  • Python - Virtual Environment
  • Python - Basic Syntax
  • Python - Variables
  • Python - Private Variables
  • Python - Data Types
  • Python - Type Casting
  • Python - Unicode System
  • Python - Literals
  • Python - Operators
  • Python - Arithmetic Operators
  • Python - Comparison Operators
  • Python - Assignment Operators
  • Python - Logical Operators
  • Python - Bitwise Operators
  • Python - Membership Operators
  • Python - Identity Operators
  • Python - Walrus Operator
  • Python - Operator Precedence
  • Python - Comments
  • Python - User Input
  • Python - Numbers
  • Python - Booleans
  • Python - Floating Points
  • Python - Control Flow
  • Python - Decision Making
  • Python - If Statement
  • Python - If else
  • Python - Nested If
  • Python - Conditional User Inputs
  • Python - Match-Case Statement
  • Python - Loops
  • Python - for Loops
  • Python - for-else Loops
  • Python - While Loops
  • Python - break Statement
  • Python - continue Statement
  • Python - pass Statement
  • Python - Nested Loops
  • Python Functions & Modules
  • Python - Functions
  • Python - Default Arguments
  • Python - Keyword Arguments
  • Python - Keyword-Only Arguments
  • Python - Positional Arguments
  • Python - Positional-Only Arguments
  • Python - Arbitrary Arguments
  • Python - Variables Scope
  • Python - Function Annotations
  • Python - Modules
  • Python - Packing and Unpacking
  • Python - Built in Functions
  • Python Strings
  • Python - Strings
  • Python - Slicing Strings
  • Python - Modify Strings
  • Python - String Concatenation
  • Python - String Formatting
  • Python - Escape Characters
  • Python - String Methods
  • Python - String Exercises
  • Python Lists
  • Python - Lists
  • Python - Access List Items
  • Python - Change List Items
  • Python - Add List Items
  • Python - Remove List Items
  • Python - Loop Lists
  • Python - List Comprehension
  • Python - Sort Lists
  • Python - Copy Lists
  • Python - Join Lists
  • Python - List Methods
  • Python - List Exercises
  • Python Tuples
  • Python - Tuples
  • Python - Access Tuple Items
  • Python - Update Tuples
  • Python - Unpack Tuples
  • Python - Loop Tuples
  • Python - Join Tuples
  • Python - Tuple Methods
  • Python - Namedtuple
  • Python - Tuple Exercises
  • Python Sets
  • Python - Sets
  • Python - Access Set Items
  • Python - Add Set Items
  • Python - Remove Set Items
  • Python - Loop Sets
  • Python - Join Sets
  • Python - Copy Sets
  • Python - Set Operators
  • Python - Set Methods
  • Python - Set Exercises
  • Python Dictionaries
  • Python - Dictionaries
  • Python - Access Dictionary Items
  • Python - Change Dictionary Items
  • Python - Add Dictionary Items
  • Python - Remove Dictionary Items
  • Python - Dictionary View Objects
  • Python - Loop Dictionaries
  • Python - Copy Dictionaries
  • Python - Nested Dictionaries
  • Python - Dictionary Methods
  • Python - Dictionary Exercises
  • Python Arrays
  • Python - Arrays
  • Python - Access Array Items
  • Python - Add Array Items
  • Python - Remove Array Items
  • Python - Loop Arrays
  • Python - Copy Arrays
  • Python - Reverse Arrays
  • Python - Sort Arrays
  • Python - Join Arrays
  • Python - Array Methods
  • Python - Array Exercises
  • Python File Handling
  • Python - File Handling
  • Python - Write to File
  • Python - Read Files
  • Python - Renaming and Deleting Files
  • Python - Directories
  • Python - File Methods
  • Python - OS File/Directory Methods
  • Python - OS Path Methods
  • Object Oriented Programming
  • Python - OOPs Concepts
  • Python - Classes & Objects
  • Python - Class Attributes
  • Python - Class Methods
  • Python - Static Methods
  • Python - Constructors
  • Python - Access Modifiers
  • Python - Inheritance
  • Python - Multiple Inheritance
  • Python - Multilevel Inheritance
  • Python - Polymorphism
  • Python - Method Overriding
  • Python - Method Overloading
  • Python - Dynamic Binding
  • Python - Dynamic Typing
  • Python - Abstraction
  • Python - Encapsulation
  • Python - Interfaces
  • Python - Packages
  • Python - Inner Classes
  • Python - Anonymous Class and Objects
  • Python - Singleton Class
  • Python - Wrapper Classes
  • Python - Enums
  • Python - Reflection
  • Python - Data Classes
  • Python Errors & Exceptions
  • Python - Syntax Errors
  • Python - Exceptions
  • Python - try-except Block
  • Python - try-finally Block
  • Python - Raising Exceptions
  • Python - Exception Chaining
  • Python - Nested try Block
  • Python - User-defined Exception
  • Python - Logging
  • Python - Assertions
  • Python - Warnings
  • Python - Built-in Exceptions
  • Python - Debugger (PDB)
  • Python Multithreading
  • Python - Multithreading
  • Python - Thread Life Cycle
  • Python - Creating a Thread
  • Python - Starting a Thread
  • Python - Joining Threads
  • Python - Naming Thread
  • Python - Thread Scheduling
  • Python - Thread Pools
  • Python - Main Thread
  • Python - Thread Priority
  • Python - Daemon Threads
  • Python - Synchronizing Threads
  • Python Synchronization
  • Python - Inter-thread Communication
  • Python - Thread Deadlock
  • Python - Interrupting a Thread
  • Python Networking
  • Python - Networking
  • Python - Socket Programming
  • Python - URL Processing
  • Python - Generics
  • Python Libraries
  • NumPy Tutorial
  • Pandas Tutorial
  • SciPy Tutorial
  • Matplotlib Tutorial
  • Django Tutorial
  • OpenCV Tutorial
  • Python Miscellenous
  • Python - Date & Time
  • Python - Maths
  • Python - Iterators
  • Python - Generators
  • Python - Generator Expressions
  • Python - Lambda Expressions
  • Python - Closures
  • Python - Decorators
  • Python - Recursion
  • Python - Reg Expressions
  • Python - PIP
  • Python - Database Access
  • Python - Weak References
  • Python - Serialization
  • Python - Templating
  • Python - Output Formatting
  • Python - Performance Measurement
  • Python - Data Compression
  • Python - CGI Programming
  • Python - XML Processing
  • Python - GUI Programming
  • Python - Command-Line Arguments
  • Python - Docstrings
  • Python - JSON
  • Python - Sending Email
  • Python - Further Extensions
  • Python - Tools/Utilities
  • Python - Odds and Ends
  • Python - GUIs
  • Python Advanced Concepts
  • Python - Abstract Base Classes
  • Python - Custom Exceptions
  • Python - Higher Order Functions
  • Python - Object Internals
  • Python - Memory Management
  • Python - Metaclasses
  • Python - Metaprogramming with Metaclasses
  • Python - Mocking and Stubbing
  • Python - Monkey Patching
  • Python - Signal Handling
  • Python - Type Hints
  • Python - Automation Tutorial
  • Python - Humanize Package
  • Python - Context Managers
  • Python - Coroutines
  • Python - Descriptors
  • Python - Diagnosing and Fixing Memory Leaks
  • Python - Immutable Data Structures
  • Python - Domain Specific Language (DSL)
  • Python - Data Model
  • Python Useful Resources
  • Python - Questions & Answers
  • Python - Interview Questions & Answers
  • Python - Online Quiz
  • Python - Quick Guide
  • Python - Reference
  • Python - Cheatsheet
  • Python - Projects
  • Python - Useful Resources
  • Python - Discussion
  • Python Compiler
  • NumPy Compiler
  • Matplotlib Compiler
  • SciPy Compiler
Selected Reading
  • UPSC IAS Exams Notes
  • Developer's Best Practices
  • Questions and Answers
  • Online Resume Builder
  • HR Interview Questions
  • Computer Glossary
  • Who is Who

Python - Descriptors



Previous
Quiz
Next

Python Descriptors

Python Descriptors are a way to customize the access, assignment and deletion of object attributes. They provide a powerful mechanism for managing the behavior of attributes by defining methods that get, set and delete their values. Descriptors are often used to implement properties, methods and attribute validation.

A descriptor is any object that implements at least one of the methods such as __get__, __set__ and __delete__. These methods control how an attribute's value is accessed and modified.

How Python Descriptors Work?

When an attribute is accessed on an instance then Python looks up the attribute in the instance's class. If the attribute is found and it is a descriptor then Python invokes the appropriate descriptor method instead of simply returning the attribute's value. This allows the descriptor to control what happens during attribute access.

The descriptor protocol is a low-level mechanism that is used by many high-level features in Python such as properties, methods, static methods and class methods. Descriptors can be used to implement patterns like lazy loading, type checking and computed properties.

Descriptor Methods

Python Descriptors involve three main methods namely __get__(), __set__() and __delete__(). As we already discussed above these methods control the behavior of attribute access, assignment and deletion, respectively.

1. The __get__() Method

The __get__() method in descriptors is a key part of the descriptor protocol in Python. It is called to retrieve the value of an attribute from an instance or from the class. Understanding how the __get__() method works is crucial for creating custom descriptors that can manage attribute access in sophisticated ways.

Syntax

The following is the syntax of Python Descriptor __get__ method −

def __get__(self, instance, owner):
   """
   instance: the instance that the attribute is accessed through, or None when accessed through the owner class.
   owner: the owner class where the descriptor is defined.
   """

Parameters

Below are the parameters of this method −

  • self: The descriptor instance.
  • instance: The instance of the class where the attribute is accessed. It is None when the attribute is accessed through the class rather than an instance.
  • owner: The class that owns the descriptor.

Example

Following is the basic example of __get__() method in which it returns the stored value _value when obj.attr is accessed −

class Descriptor:
   def __get__(self, instance, owner):
      if instance is None:return self
      return instance._value

class MyClass:
   attr = Descriptor()

   def __init__(self, value):
      self._value = value

obj = MyClass(42)
print(obj.attr)  

Output

42

2. The __set__() Method

The __set__() method is part of the descriptor protocol in Python and is used to control the behavior of setting an attribute's value. When an attribute managed by a descriptor is assigned a new value then the __set__() method is called by allowing the user to customize or enforce rules for the assignment.

Syntax

The following is the syntax of Python Descriptor __set__() method −

def __set__(self, instance, value):
    """
    instance: the instance of the class where the attribute is being set.
    value: the value to assign to the attribute.
    """

Parameters

Below are the parameters of this method −

  • self: The descriptor instance.
  • instance: The instance of the class where the attribute is being set.
  • value: The value being assigned to the attribute.

Example

Following is the basic example of __set__() method in which ensures that the value assigned to attr is an integer −

class Descriptor:
    def __set__(self, instance, value):
        if not isinstance(value, int):
            raise TypeError("Value must be an integer")
        instance._value = value

class MyClass:
    attr = Descriptor()

    def __init__(self, value):
        self.attr = value

obj = MyClass(42)
print(obj.attr)  
obj.attr = 100
print(obj.attr)  

Output

<__main__.Descriptor object at 0x000001E5423ED3D0>
<__main__.Descriptor object at 0x000001E5423ED3D0>

3. The __delete__() Method

The __delete__() method in the descriptor protocol allows us to control what happens when an attribute is deleted from an instance. This can be useful for managing resources, cleaning up or enforcing constraints when an attribute is removed.

Syntax

The following is the syntax of Python Descriptor __delete__() method −

def __delete__(self, instance):
    """
    instance: the instance of the class from which the attribute is being deleted.
    """

Parameters

Below are the parameters of this method −

  • self: The descriptor instance.
  • instance: The instance of the class where the attribute is being deleted.

Example

Following is the basic example of __set__() method in which ensures that the value assigned to attr is an integer −

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

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

   def __set__(self, instance, value):
      instance.__dict__[self.name] = value

   def __delete__(self, instance):
      if self.name in instance.__dict__:
         print(f"Deleting {self.name} from {instance}")
         del instance.__dict__[self.name]
      else:
         raise AttributeError(f"{self.name} not found")

class Person:
   name = LoggedDescriptor("name")
   age = LoggedDescriptor("age")

   def __init__(self, name, age):
      self.name = name
      self.age = age

# Example usage
p = Person("Tutorialspoint", 30)
print(p.name)  
print(p.age)   

del p.name    
print(p.name) 

del p.age    
print(p.age)   

Output

Tutorialspoint
30
Deleting name from <__main__.Person object at 0x0000021A1A67E2D0>
None
Deleting age from <__main__.Person object at 0x0000021A1A67E2D0>
None

Types of Python Descriptors

In Python descriptors can be broadly categorized into two types based on the methods they implement. They are −

  • Data Descriptors
  • Non-data Descriptors

Let's see about the two types of python descriptors in detail for our better understanding.

1. Data Descriptors

Data descriptors are a type of descriptor in Python that define both __get__()and __set__() methods. These descriptors have precedence over instance attributes which meand that the descriptors __get__()and __set__() methods are always called, even if an instance attribute with the same name exists.

Example

Below is the example of a data descriptor that ensures an attribute is always an integer and logs access and modification operations −

class Integer:
   def __get__(self, instance, owner):
      print("Getting value")
      return instance._value

   def __set__(self, instance, value):
      print("Setting value")
      if not isinstance(value, int):
         raise TypeError("Value must be an integer")
      instance._value = value

   def __delete__(self, instance):
      print("Deleting value")
      del instance._value

class MyClass:
   attr = Integer()

# Usage
obj = MyClass()
obj.attr = 42  
print(obj.attr)  
obj.attr = 100  
print(obj.attr)  
del obj.attr   

Output

Setting value
Getting value
42
Setting value
Getting value
100
Deleting value

2. Non-data Descriptors

Non-data descriptors are a type of descriptor in Python that define only the __get__() method. Unlike data descriptors, non-data descriptors can be overridden by instance attributes. This means that if an instance attribute with the same name exists then it will take precedence over the non-data descriptor.

Example

Following is an example of a non-data descriptor that provides a default value if the attribute is not set on the instance −

class Default:
   def __init__(self, default):
      self.default = default

   def __get__(self, instance, owner):
      return getattr(instance, '_value', self.default)

class MyClass:
   attr = Default("default_value")

# Usage
obj = MyClass()
print(obj.attr)  
obj._value = "Tutorialspoint"
print(obj.attr) 

Output

default_value
Tutorialspoint

Data Descriptors Vs. Non-data Descriptors

Understanding the differences between Data Descriptors and Non-data Descriptors of python Descriptors is crucial for leveraging their capabilities effectively.

Criteria Data Descriptors Non-Data Descriptors
Definition Implements both __get__(), __set__() methods, and the __delete__() method optionally. Implements only __get__() method.
Methods __get__(self, instance, owner)
__set__(self, instance, value)
__delete__(self, instance) (optional)
__get__(self, instance, owner)
Precedence Takes precedence over instance attributes. Overridden by instance attributes.
Use Cases Attribute validation and enforcement,
Managed attributes (e.g., properties),
Logging attribute access and modification,
Enforcing read-only attributes.
Method binding,
Caching and,
Providing default values..

Finally we can say Descriptors in Python provide a powerful mechanism for managing attribute access and modification. Understanding the differences between data descriptors and non-data descriptors as well as their appropriate use cases is essential for creating robust and maintainable Python code.

By leveraging the descriptor protocol developers can implement advanced behaviors such as type checking, caching and read-only properties.

Tutorix - AI Tutor
Previous Quiz Next
Advertisements
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.