Skip to main content

Maintenance License: MIT codecov

descriptor

A simple, fast, typed, and tested abstract and base classes for a python3.6+ Non Data Descriptor, Data Descriptor, and Slottable Data Descriptor. The goal is to aid in the creation of descriptors allowing other developers to make descriptors for their own use case.

Key Features:

  • Easy: Flexable and easy to inherit the prebuilt Non Data Descriptors, Data Descriptors, and Slottable Data Descriptors to create your own descriptors.
  • Great Developer Experience: Being fully typed makes it great for editor support.
  • Fully Tested: Our test suit fully tests the functionality to ensure that all of the classes in this module run as expected.

Installation

pip install descriptor

Table of Contents

Objects Provided in this Module

Non Data Descriptors

A non-data descriptor in Python is a type of descriptor that only implements the __get__() method. Descriptors are a way to customize attribute access in Python. When an attribute is accessed on an object, Python checks if a descriptor exists for that attribute in the class or its ancestors. If found, the descriptor's __get__() method is called to determine the final value of the attribute.

Class Description
AbstractNonDataDescriptor Abstract Base Class for creating Non Data Descriptors.

Data Descriptors

A data descriptor in Python is a type of descriptor that implements both __get__() and either __set__() or __delete__(). Data descriptors allow you to define custom behavior for attribute access, including setting or deleting the attribute in addition to retrieving its value.

Class Description
AbstractDataDescriptor Abstract Base Class for creating Data Descriptors.
BaseDataDescriptor Base Class for creating Data Descriptors. Provides the same functionality as a standard attribute.
DefaultDescriptor A Data Descriptor that has a default value.
ReadOnly A Data Descriptor that is read only.

Slottable Data Descriptors

A Data Descriptor that plays well with __slots__. This module was inspired by Dr. Fred Baptiste fbaptiste.

The slottable data descriptor has the following advantages:

  1. Has instance specific storage
  2. Does not use the instance for storage, thus works with slots. __slots__ = "__weakref__" must be set.
  3. Handles non hashable instances
  4. Data storage is clean.
Class Description
AbstractSlottableDataDescriptor Abstract Base Class for creating Slottable Data Descriptors.
BaseSlottableDataDescriptor Base Class for creating Slottable Data Descriptors. Provides the same functionality as a standard attribute.
SlottableDefaultDescriptor A Slottable Data Descriptor that has a default value.

Non Data Descriptor Examples

AbstractNonDataDescriptor

Simple way to Inherit from AbstractNonDataDescriptor to create your own Non Data Descriptor.

from base_descriptor import AbstractNonDataDescriptor


class SquareDescriptor(AbstractNonDataDescriptor):
    def __get__(self, instance, owner=None):
        if instance is None:
            # Access through the class, return the descriptor itself
            return self
        return instance._value ** 2


class MyClass:
    square = SquareDescriptor()

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


# Create an instance of MyClass
my_instance = MyClass(5)

# Access the square attribute using the descriptor
# This will calculate and return the square
print(my_instance.square)  # 25

Data Descriptor Examples

ReadOnly

from base_descriptor import ReadOnly


class Person:
    name = ReadOnly("Guido")


person = Person()
print(person.name)  # Guido
person.name = "Raymond"  # raises AttributeError

DefaultDescriptor

Default Descriptor that provides a default value for the attribute.

from base_descriptor import DefaultDescriptor


class Person:
    name = DefaultDescriptor(default="Guido")


print(Person.name)  # <data_descriptor.DefaultDescriptor object at ...>
person = Person()
print(person.name)  # Guido
person.name = "Raymond"
print(person.name)  # Raymond

BaseDataDescriptor

Provides the same functionality as a standard attribute. It enables you to create your own Data Descriptor by overriding the __set_name__(), __set__(), __get__(), or __delete__() methods to match your requirements.

from base_descriptor import BaseDataDescriptor


class Plus2(BaseDataDescriptor):
    def __set__(self, instance, value):
        value = value + 2
        instance.__dict__[self._property_name] = value


class Foo:
    bar = Plus2()


foo = Foo()
foo.bar = 1
print(foo.bar)  # 3

AbstractDataDescriptor

Provides an Abstract Base Class that can be inherited from to help create your own Data Descriptors.

from base_descriptor import AbstractDataDescriptor


class MyDataDescriptor(AbstractDataDescriptor):
    def __init__(self):
        self._value = None

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

    def __set__(self, instance, value):
        self._value = value

    def __delete__(self, instance):
        self._value = None


class MyClass:
    my_data_descriptor = MyDataDescriptor()


obj = MyClass()
obj.my_data_descriptor = 1
print(obj.my_data_descriptor)  # 1

Slottable Data Descriptors

SlottableDefaultDescriptor

Slottable Default Descriptor that provides a default value for the attribute.

from base_descriptor import SlottableDefaultDescriptor


class Person:
    __slots__ = "__weakref__"
    first_name = SlottableDefaultDescriptor(default="Guido")


person = Person()
print(person.first_name)  # Guido
person.first_name = "Raymond"
print(person.first_name)  # Raymond

BaseSlottableDataDescriptor

Provides the same functionality as a standard attribute. It enables you to create your own Slottable Data Descriptor by overriding the __set_name__(), __set__(), __get__(), or __delete__() methods to match your requirements.

from base_descriptor import BaseSlottableDataDescriptor


class MyDescriptor(BaseSlottableDataDescriptor):
    def __set__(self, instance, value):
        print(f"Setting {self._property_name} to {value}")
        instance.__dict__[self._property_name] = value


class Foo:
    __slots__ = "__weakref__"
    bar = MyDescriptor()


foo = Foo()
foo.bar = 1
print(foo.bar)  # 1

References

This module was heavily inspired by the following resources:

  1. Python Deep Dive: Part 4

  2. Descriptor HowTo Guide

Release files for base-descriptor 1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for base-descriptor 1.0
File Size Uploaded
base-descriptor-1.0.tar.gz 9.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for base-descriptor 1.0
File Interpreter ABI Platform
base_descriptor-1.0-py3-none-any.whl Python 3 none any Details

Total release size: 20.2 kB

Release files / base-descriptor-1.0.tar.gz

Download URL base-descriptor-1.0.tar.gz
Size 9.8 kB
Tags Source
SHA-256 checksum
How to use checksums
8b512f6ed5520b93dbb06996f1fa00b401dabafdab2b2323397568bd79d24035
BLAKE2b-256 checksum
How to use checksums
0ecc487bf18737cdecaa20615950ab5f8756f285d4443c58bc31317072daf12f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.18

Release files / base_descriptor-1.0-py3-none-any.whl

Download URL base_descriptor-1.0-py3-none-any.whl
Size 10.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4b47fda5b7f6fbabda5d30877e73e604bb7ae59fc873477b27c0b89a54b58947
BLAKE2b-256 checksum
How to use checksums
49b4c9a18e9690324f8caa2d2f1522c7a1299edac7d3c080b9a600c24da622ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.18

Release history Release notifications | RSS feed

1.2

2 release files

1.1

2 release files

This release

1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page