Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære __get__, __set__, __delete__ | What Descriptors Are
Python Descriptors Explained

__get__, __set__, __delete__

Sveip for å vise menyen

A descriptor is any object that defines at least one of three special methods: __get__, __set__, or __delete__. When an instance of such an object is assigned as a class attribute, Python's attribute lookup machinery calls these methods automatically instead of returning the object directly.

The Three Methods

__get__(self, obj, objtype=None) is called when the attribute is read. obj is the instance accessing the attribute (None when accessed from the class). objtype is the class:

12345678910111213
# A minimal read-only descriptor class Descriptor: def __get__(self, obj, objtype=None): if obj is None: return self # Accessed from the class – return the descriptor itself return f"Value accessed on {obj.__class__.__name__}" class Report: status = Descriptor() # Descriptor assigned as a class attribute report = Report() print(report.status) # "Value accessed on Report" print(Report.status) # The Descriptor object itself

__set__(self, obj, value) is called when the attribute is written:

1234567891011121314151617181920212223242526
# A descriptor that validates and stores a value class PositiveNumber: def __set_name__(self, owner, name): self._name = name # Storing the attribute name for error messages def __get__(self, obj, objtype=None): if obj is None: return self return obj.__dict__.get(self._name) def __set__(self, obj, value): if not isinstance(value, (int, float)) or value <= 0: raise ValueError(f"{self._name} must be a positive number, got {value!r}") obj.__dict__[self._name] = value class Product: price = PositiveNumber() def __init__(self, name, price): self.name = name self.price = price # Triggers __set__ laptop = Product("ThinkPad", 1200.0) print(laptop.price) # 1200.0 laptop.price = -50 # Raises ValueError

__delete__(self, obj) is called when the attribute is deleted with del:

1234567891011121314151617181920212223242526272829
# Adding deletion support to the descriptor class PositiveNumber: def __set_name__(self, owner, name): self._name = name def __get__(self, obj, objtype=None): if obj is None: return self return obj.__dict__.get(self._name) def __set__(self, obj, value): if not isinstance(value, (int, float)) or value <= 0: raise ValueError(f"{self._name} must be a positive number, got {value!r}") obj.__dict__[self._name] = value def __delete__(self, obj): obj.__dict__.pop(self._name, None) print(f"{self._name} removed from {obj!r}") class Product: price = PositiveNumber() def __init__(self, name, price): self.name = name self.price = price laptop = Product("ThinkPad", 1200.0) del laptop.price # Triggers __delete__ print(laptop.__dict__) # {'name': 'ThinkPad'}

__set_name__

__set_name__(self, owner, name) is called automatically when the descriptor is assigned to a class attribute. It gives the descriptor access to its own attribute name without hardcoding it:

1234567891011121314151617
# __set_name__ receives the class and attribute name at class creation time class TrackedAttribute: def __set_name__(self, owner, name): print(f"Descriptor assigned to {owner.__name__}.{name}") self._name = name def __get__(self, obj, objtype=None): if obj is None: return self return obj.__dict__.get(self._name) def __set__(self, obj, value): obj.__dict__[self._name] = value class Invoice: amount = TrackedAttribute() # Prints: Descriptor assigned to Invoice.amount currency = TrackedAttribute() # Prints: Descriptor assigned to Invoice.currency
question mark

What does __get__ receive as obj when the descriptor is accessed from the class rather than from an instance?

Velg det helt riktige svaret

Alt var klart?

Hvordan kan vi forbedre det?

Takk for tilbakemeldingene dine!

Seksjon 1. Kapittel 2

Spør AI

expand

Spør AI

ChatGPT

Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår

Seksjon 1. Kapittel 2
some-alt