Do you know what Python descriptors are?

Descriptor is a protocol in python that enables data to have a saying about what happens on lookup, storage and deletion.

A great use case for descriptors are data validation.

#100DaysOfCode #freeCodeCamp

🧵👇
When a class defines `__get__`, `__set__` or `__delete__` it becomes a descriptor and is called with the `.` (dot) operator.

By implementing validators as descriptors we push everything validation-related outside the class that holds data.
👇
Let's define two validators as descriptors.

They both store the actual value assigned in a private variable and run a validation function when a value is assigned.

Let's go over the special methods implemented 👇 class SkuValidator:     """Validates that a sclass PositiveIntValidator:     """Validates
A descriptor that ONLY implements `__get__` is called a non-data descriptor.

The method is called by the `.` dot operator when a value is accessed.

For example: logging.info(item.sku)

👇     def __get__(self, obj: Any, objtype=None) -> str:
A descriptor that implements `__get__` AND `__set__` is called a data descriptor.

The `__set__` method is called by the `.` dot operator when a value is assigned.

For example: item.sku = 'item-sku'

👇     def __set__(self, obj: Any, value: str) -> None:            def __get__(self, obj: Any, objtype=None) -> str:
A descriptor could also implement `__delete__`.

This method gets called when an attribute is deleted.

In most cases we don't need this. For simplicity I'm going to leave it out of this example.

👇
A descriptor can optionally implement `__set_name__`. This is not part of the descriptor protocol.

The method is called when the parent class is created.

Useful to store the attribute name the descriptor is assigned to.    def __set_name__(self, owner: Any, name: str) -> None:
Descriptors only work when assigned to class variables.

A non-data descriptor can be overridden by an instance variable.

A data descriptor will NOT be overridden by instance variables.
👇 class DataDescriptor:     def __get__(self, obj: Any, objtyp
We can use the previously defined descriptors to validate the data in a dataclass like this.

👇 @dataclass class Item:     sku: str = cast(str, SkuValidatorclass SkuValidator:     """Validates that a sclass PositiveIntValidator:     """Validates
A dataclass using descriptors can be instantiated as normal.

The main downside of using descriptors together with dataclasses is that we have to use typing.cast to avoid mypy errors.

👇 @dataclass class Item:     sku: str = cast(str, SkuValidatorInitialize an Item object with correct values  item = Item(s
If we initialize an instance of a dataclass with validator descriptors in its fields with invalid values we get an `AttributeError`

👇 Pass an invalid sku  Item(sku="sku", quantity=1)  Pass an invalid quantity  Item(sku="item-sku", qua
Using dataclasses together with descriptors means apart from validation we can also get serialization out of the box.

👇 Now we have a class that validates its inputs and can be eas
You can play around with the code in this thread using this notebook:
mybinder.org/v2/gh/rmcomple…

Read more on descriptors: docs.python.org/3/howto/descri…

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Josue🧪

Josue🧪 Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @rmcomplexity

8 Jan
Do you know how `self` gets injected into a method in Python?

Methods defined in a class are function objects.

Methods in a class instance are **bound methods**

A thread 👇
#100DaysOfCode #freeCodeCamp  import logging from datacl...
A function object is implemented as a descriptor.

Which means when we access its value we are calling the __get__method in the function object.

👇  A method in an instance is...
When you call a method in an object instance the function descriptor injects the instance as the first argument.

In fact, we can manually call the descriptor from the class definition to show how it's actually being called:

👇 And, we can double check th...
Read 4 tweets
30 Nov 20
👩‍🏫 Are you mentoring?
🧑‍🎓Do you have a mentor?

Teaching others reinforces what you know!

A mentor can help you identify the things you need to work on to become better at your job

7 key things about finding a mentor and being a mentor

🧵👇
1⃣What is a mentor?

A person who help you improve professionally and personally

Sometimes is someone with whom you can have an honest conversation about anything

In a Mentor - Mentee relationship both parties benefit. But as a mentee always be respectful of your mentor's time.
2⃣How do I find a mentor?

You first have to show interest in growing and you have to be patient

Find people with experience in the fields you want to grow and make yourself noticed

You can contribute to some body else's work, ask questions or volunteer

Remember to be patient
Read 8 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!

Follow Us on Twitter!