Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Describing Descriptors

Describing Descriptors

Oftentimes beginner programmers go through traditional features when learning a language. For Python beginners this might involve variables, control structures like if-statements, while and for loops, dictionaries, and finally classes. However, if we read the Python documentation we find that another feature that can be used in Python is that of the descriptor protocol. Descriptors allow the programmer to override the storing and retrieving of different class instance variables such that special behaviours can be followed. For example, we might want some variable to follow some special validation. We could do this using __setattr__ on the containing class but perhaps we want to reuse the validation in another class, or we want other validations for other variables and we don’t want __setattr__ to become a huge if/elif/else block. In this talk, I will walk attendees through what a descriptor is, what use cases they can use them in, how to implement a descriptor, and common descriptors in the Python ecosystem that users may or may not have identified as descriptors (often just referred to as magic).

Matthew Egan

August 25, 2018
Tweet

Other Decks in Technology

Transcript

  1. Describing Descriptors
    Matthew Egan
    1

    View full-size slide

  2. • Matthew Egan
    • DiviPay
    • Sydneysider
    • mattjegan
    • NullMatthew
    • https://mattjegan.com
    Any opinions conveyed in this talk are my own and not my employers
    2

    View full-size slide

  3. Thanks
    • Adam Jacquier-Parr - www.github.com/aljp
    • Christopher Di Bella - www.cjdb.com.au
    • Daniel Kniaz & Russell Martin - www.divipay.com
    3

    View full-size slide

  4. Who is this for?
    • Everyone who is comfortable with classes in Python
    • I won’t be covering meta-classes in this talk
    4

    View full-size slide

  5. Why Descriptors?
    • Descriptors are a feature of Python that is often overlooked
    • Used primarily by library developers rather than application
    developers
    5

    View full-size slide

  6. PSA: Use Python 3
    • This talk uses Python 3.6+
    • Python 2 is now at end of life and won’t be maintained after 2020
    • Long live Python 3!
    6

    View full-size slide

  7. What?
    • A problem
    • Some solutions
    • A better solution (hint: it’s descriptors)
    7

    View full-size slide

  8. Classes - A refresher
    8

    View full-size slide

  9. A Problem
    • How can we make sure the name is always capitalized?
    9

    View full-size slide

  10. The current Person class: Our dream Person class:
    10

    View full-size slide

  11. __setattr__
    • Is called whenever we try to set an instance variable
    • Takes the calling object, the name of the attribute being set, and
    the new value
    11

    View full-size slide

  12. __setattr__
    12

    View full-size slide

  13. __setattr__
    • This does the job
    • Locked to this class
    • Gets out of hand with many properties
    14

    View full-size slide

  14. @property and @name.setter
    15

    View full-size slide

  15. @property and @name.setter
    • This does the job
    • Locked to this class
    • Gets out of hand with
    many properties
    17

    View full-size slide

  16. What about…
    Simple Class Code + Reusable = Maintainable
    18

    View full-size slide

  17. Furthermore what about…
    Simple Class Code + Reusable = Maintainable
    19

    View full-size slide

  18. The Descriptor Protocol
    • Python exposes the descriptor protocol as a way to customize the
    storing and retrieval of instance attributes
    • Self-contained
    • Reusable
    20

    View full-size slide

  19. The Descriptor Protocol
    • __get__ is called when accessing the attribute
    • __set__ is called when storing the attribute
    • __delete__ is called when the attribute is being deleted
    • __set_name__ is called once when the class object is created (Python
    3.6+, PEP487)
    21

    View full-size slide

  20. The Descriptor Protocol
    0
    350,000
    700,000
    1,050,000
    1,400,000
    __get__ __set__ __delete__ __set_name__
    22

    View full-size slide

  21. __delete__
    25

    View full-size slide

  22. __set_name__
    • Only called on class creation
    26

    View full-size slide

  23. Types of Descriptors
    Data Descriptor
    Non-data
    Descriptor
    __set__
    YES
    NO
    __delete__
    YES
    27

    View full-size slide

  24. Descriptor Precedence
    Data Descriptor
    __dict__
    Non-data Descriptor
    28

    View full-size slide

  25. Non-data Descriptors
    29
    • staticmethod
    • classmethod
    • abc.abstractmethod
    • functools.partialmethod

    View full-size slide

  26. WeakKeyDictionary
    30

    View full-size slide

  27. A Solution
    How do we solve our problem of capitalizing the name?
    33

    View full-size slide

  28. Use Cases
    • Replicating customisation for multiple attrs without caring about
    name
    • Django generic foreign keys
    • Validation
    • Better error messages
    35

    View full-size slide

  29. Django Generic Foreign Keys
    • Needs to store 2 values rather than 1
    36

    View full-size slide

  30. Validation
    37

    View full-size slide

  31. Error Messages
    Not nice
    Nice
    38

    View full-size slide

  32. Error Messages
    39

    View full-size slide

  33. https://bit.ly/describing-descriptors
    40
    mattjegan
    NullMatthew
    https://mattjegan.com

    View full-size slide