8 things in Python you didn't realize are descriptors

Поделиться
HTML-код
  • Опубликовано: 31 май 2024
  • Descriptors are everywhere in Python, but you may not have realized it.
    They underlie functions, properties, staticmethods, and more! In this video we take a look at 8 Python descriptors and explain the descriptor protocol.
    ― mCoding with James Murphy (mcoding.io)
    Source code: github.com/mCodingLLC/VideosS...
    descriptor docs: docs.python.org/3/howto/descr...
    staticmethods vid: • Python staticmethod an...
    super vid: • super/MRO, Python's mo...
    slots vid: • Python __slots__ and o...
    SUPPORT ME ⭐
    ---------------------------------------------------
    Patreon: / mcoding
    Paypal: www.paypal.com/donate/?hosted...
    Other donations: mcoding.io/donate
    Top patrons and donors: Jameson, Laura M, Dragos C, Vahnekie, Neel R, Matt R, Johan A, Casey G, John Martin, Mutual Information
    BE ACTIVE IN MY COMMUNITY 😄
    ---------------------------------------------------
    Discord: / discord
    Github: github.com/mCodingLLC/
    Reddit: / mcoding
    Facebook: / james.mcoding
    CHAPTERS
    ---------------------------------------------------
    0:00 Intro
    0:17 What are descriptors?
    2:08 #1 functions
    3:10 #2 properties
    5:27 #3 classmethods and staticmethods
    6:47 #4 slots
    7:42 #5 _dict_
    8:30 #6 SQLAlchemy models
    9:06 #7 validators
    10:16 #8 super lookups
    10:46 Interactions with _getattr_
    14:02 Thanks
  • НаукаНаука

Комментарии • 99

  • @xan1716
    @xan1716 Год назад +30

    Another example is cached_property: it's implemented as a non-data descriptor. It is accessed on the first call; the result is then computed and saved into the instance dictionary. Since the instance dictionary has greater priority than a non-data descriptor, successive lookups just return the value from the instance dictionary.

  • @moneyluser5711
    @moneyluser5711 10 месяцев назад +5

    One of the most useful videos in existence for understanding python objects more deeply. The delivery is so good. Only what you need, no time wasted.

  • @purevert
    @purevert Год назад +33

    Sometimes it feels like he can read my mind and make tutorials on things I will need. Thanks for always making tutorials that are so detailed.

    • @redmastern576
      @redmastern576 Год назад

      RUclips algorithms and your interest are tuned to this. He’s making these videos, RUclips Ml just knows you too well.

  • @Veptis
    @Veptis Год назад +6

    The more videos I watch on your channel the more I learn. But I also feel more and more alien to using python for 3+ years and not ever needing or noticing most of the stuff.

    • @isaacingleby8771
      @isaacingleby8771 5 месяцев назад +1

      Most of the stuff on this channel you shouldn't be doing in my opinion.
      I watch this channel to patch some holes in my understanding of what may be happening under the hood, but applying this knowledge to production code is a bad idea. Most of it is just complication for complications sake.
      Object attribute setting/getting described in this video is something most devs will need to tweak at some point.
      However, if a dev in my team tried to do most of what this guy shows off I would tell them in no uncertain terms to rewrite the code.
      Such a dev is creating problems down the line that will have to be picked up by some sorry soul for some wothless brownie points from less experienced devs who don't have the experience/confidence in Python to call out BS when they see it.

  • @glorytoarstotzka330
    @glorytoarstotzka330 Год назад +10

    amazing timing, literally the other day I spent quite a while to read the whole python official docs on descriptors.
    often times I see the "I was just needing this, thanks for the tutorial", but now I can finally relate to this kind of moment

  • @loere
    @loere Год назад +1

    it took me 2 years to finally find a python video that still teached me stuff

  • @rb1471
    @rb1471 Год назад +1

    This video made me realize that despite trying to learn more python through your videos, there's still a tone I'll never get lol.
    Me: "How does this work?"
    Video "Oh I made a video on that"
    Repeat x10

  • @japedr
    @japedr Год назад +18

    Awesome. Finally I got to understand the descriptor protocol magic. Thank you so much.

  • @dennismuller1141
    @dennismuller1141 Год назад +11

    everytime I watch one of your videos I feel like I know nothing about python xD

  • @PanicAtTehCisco
    @PanicAtTehCisco Год назад +7

    Numpy also uses this for matrix transposition when you do m.T, implemented as a property

  • @sharkinahat
    @sharkinahat Год назад +49

    dict._ _dict_ _['_ _dict_ _'] isn't a dict? Mind blown.

    • @JustRollin
      @JustRollin Год назад +7

      No need to be a dict about it. Sorry, I'm a dicted to puns.

  • @gregorymorse8423
    @gregorymorse8423 Год назад +3

    This is valuable content. Learning more advanced technical nuanced aspects of Python is very interesting and useful 👍

  • @Joooooooooooosh
    @Joooooooooooosh Год назад +5

    This would be good for some of the things you'd typically use implicit conversions for in C#. Like OrderNumber -> String.

  • @MrDowntemp0
    @MrDowntemp0 Год назад +1

    Is it possible to use the descriptors for field validation in a class that uses slots?

  • @AntonioZL
    @AntonioZL Год назад +6

    The python master!

  • @aaronm6675
    @aaronm6675 Год назад

    This was good to hear

  • @xan1716
    @xan1716 Год назад +2

    I'm not sure 12:40 is entirely correct: if you have `class Foo: d = Desc()` where `Desc` is some descriptor class that for example always returns a constant (say, 42), and if we further have `class Bar(Foo): d = 12` for instance, then `b = Bar(); print(b.d)` prints the class var, not the non-data descriptor, since it precedes it in the mro.

    • @mCoding
      @mCoding  Год назад +3

      In your example you have overwritten the descriptor with the value 12, which is not a descriptor, so the logic goes "12 not a data descriptor, next. instance variable not found in dunder dict, next. 12 is not a non-data descriptor, next. return the class variable 12. The first step in the process is always to look up the class variable in MRO, but that variable is only _returned_ if it is not a data descriptor, nothing was found in the object's dict, and it is not a non-data descriptor. Here is the official doc's pure Python implementation where you can see the series of fallbacks (docs.python.org/3/howto/descriptor.html?highlight=attribute#invocation-from-an-instance). Hopefully this explains it better than I did.

    • @xan1716
      @xan1716 Год назад +1

      @@mCoding oh I see (hadn't looked this up in the docs before -- thanks for the link!). So basically, i) only the first hit in the mro counts, ii) the order is: data descriptor > instance dict > whatever else. If "whatever else" happens to be a descriptor (necessarily non-data) invoke it, else just return it (in which case it's just a class variable)

  • @royler8848
    @royler8848 Год назад

    Amazing video

  • @oida10000
    @oida10000 Год назад

    Also with @property.setter you have the advantages of a proper setter method, which might does some checks without having to call a setter method directly.

  • @gloweye
    @gloweye Год назад +8

    In `__getattribute__`, in the (very rare) case I use it, i'd use super().__getattribute__ instead of object.__getattribute__
    Ugh, youtube comments format everything weird and I can't get it right. But I think my meaning comes through.

    • @osolomons
      @osolomons Год назад +6

      Petition for markdown comment formatting!

    • @d00dEEE
      @d00dEEE Год назад +3

      @@osolomons Yeah, I'd +1 that except that youtoob comments are a black hole and after you've made some effort towards intelligent content and formatted it nicely, only three people will ever see it. Better to have people like James have their own forums/discourse/whatever, where we can go comment and have those comments discoverable.

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 Год назад +1

      ‗try‗ using ‗this‗ character instead. Best I can do ...

    • @anon_y_mousse
      @anon_y_mousse Год назад +1

      @@osolomons They actually do to a tiny extent. If I use an *asterisk* around a word and the content creator has it enabled, it'll make it bold, for instance.

  • @zefciu
    @zefciu Год назад +1

    I still don’t get, why staticmethod is a descriptor. After all defining a method as static is about preventing its binding. So it shouldn’t require any special access logic. Could you explain this more?

  • @alexandergoryunov8021
    @alexandergoryunov8021 Год назад +3

    Umm, I don't get the per-class vs per-attr distinction. The get/set methods are also defined on an instance, so you can get the exact same behavior by defining __getattr__ on the Descriptor class instead of __get__.

    • @nnirr1
      @nnirr1 Год назад +2

      `_getattr_` wouldn't work that way when defined on the descriptor itself. When i call instance.descriptor, only the instance's `_getattr_` will be (potentially!) called and will return the instance of the descriptor itself. In order to call the descriptor's `_getattr_` i would have to do something like instance.descriptor.x.
      However, by defining `_get_` on the descriptor itself, python will do that extra step and instead of just returning the descriptor, it would invoke the descriptor's _get_.

    • @alexandergoryunov8021
      @alexandergoryunov8021 Год назад +2

      @@nnirr1 Oh, okay - that makes sense. It's still too niche for this late at night though ) For instance the fact that both _get_ and _set_ appear to work on an instance of the class but only _get_ seems to work on the class itself.

    • @nnirr1
      @nnirr1 Год назад +2

      @@alexandergoryunov8021 Hmmm didnt think about it but it it IS kinda inconsistent in that way. I can see why they did that but i can also understand why it is confusing as well

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 Год назад +3

      Remember, every function is a descriptor -- it has a ‗‗get‗‗ method, but no ‗‗set‗‗, ‗‗delete‗‗ or ‗‗set‗name‗‗, which makes it a non-data descriptor.

  • @HitBoxMaster
    @HitBoxMaster Год назад

    What font are you using?

  • @marcomaiocchi5808
    @marcomaiocchi5808 Год назад +1

    I thought I knew python till I saw this video. Goddamnit.

  • @GertCuykens
    @GertCuykens Год назад +1

    just when I think I start to understand python, youtube is saying hold my beer ...

  • @__mrmino__
    @__mrmino__ Год назад +4

    No, you cannot just use function calls in places of properties: imagine having an instance field in your public API. Now try to make that field dynamic - if not for properties, you couldn't do so without breaking backwards compatibility.

    • @sadhlife
      @sadhlife Год назад +4

      if you want your api to always be 100% backwards compatible without properties, you could just make all the attributes private and define a get_x() for every self._x attribute. But yeah, properties are way cleaner

    • @__mrmino__
      @__mrmino__ Год назад +2

      @@sadhlife yes, hence all of the getters and setters boilerplate in Java, which, thank god, Python developers avoided.

  • @CrapE_DM
    @CrapE_DM Год назад

    I think the reason for data and non-data descriptors actually has more to do with being able to override functions on an instance rather than the caching idea, but it's all speculation.

  • @JusticeNDOU
    @JusticeNDOU Год назад +2

    hold on, what are descriptors ?

  • @anthonydesouza9983
    @anthonydesouza9983 Год назад +5

    Double Dundee Dict is my stripper name

  • @l4luchi123
    @l4luchi123 Год назад +2

    Excellent video as always!
    How about a video about slices? Especially for Numpy they play a big role, e.g. for numpy.roll. ;-)

  • @flicko0
    @flicko0 Год назад +53

    not discord gang

    • @bereck7735
      @bereck7735 Год назад +2

      Flicko, tragic is trag1c . ;)

    • @tapu_
      @tapu_ Год назад

      We meet again

    • @flicko0
      @flicko0 Год назад

      We do meet once more

  • @init1508
    @init1508 11 месяцев назад

    Cool

  • @Daniel_Zhu_a6f
    @Daniel_Zhu_a6f Год назад +1

    as somebody who programs python i wish descriptors, custom attributes, setters and getters never existed. practice proves that they are very tricky to get right. much like python's inheritance and exception systems, they are just a terrible mistake. after all, if you really need an object with variable amount of attributes, you probably just need something else (like a dictionary). it's not normal when literally any expression you write can do anything: thread suspension, caching, IO, process spawn, arbitrary flow control jumps (when throwing exceptions).
    it would be good to have some language that is 100% compatible with python but optimized for immutability of objects and types, with interfaces instead of inheritance and with normal metaprogramming techniques like templates and sanitized macros.

    • @Daniel_Zhu_a6f
      @Daniel_Zhu_a6f Год назад

      @@a2sbestos768 kotlin is quite different from java, but they are 100% compatible. same with zig and c. why can't there exist a language that has comptime-immutable types and is compiled to same bytecode as python?

  • @trag1czny
    @trag1czny Год назад +3

    discord gang 🤙🤙

    • @bereck7735
      @bereck7735 Год назад +1

      aye tragic

    • @bereck7735
      @bereck7735 Год назад +1

      You are cute

    • @trag1czny
      @trag1czny Год назад

      @@bereck7735 no u

    • @bereck7735
      @bereck7735 Год назад +1

      ​@@trag1czny cutie, how are you ;)

    • @dotmashrc
      @dotmashrc Год назад

      i didn't need to see this today

  • @nnirr1
    @nnirr1 Год назад +1

    Im writing a pickling library and when testing its behaviour with descriptors i accidentally found a bug within python's core pickle library. The c implemented classmethod descriptors (such as datetime.__dict__["now"]) were pickled into a wrong set of instructions that invoke the descriptors, returning the underlying value upon unpickling (instead of the descriptor itself)

  • @smb1397
    @smb1397 Год назад +1

    can i ask you why you pronounce tuple like that? i wanna do it like that but google says im wrong i need some sources to show my friends

    • @drdca8263
      @drdca8263 Год назад +1

      I’ve heard it both ways

    • @isodoubIet
      @isodoubIet Год назад

      I mean it's not spelled tupple

  • @rosscousens6263
    @rosscousens6263 Год назад

    Please write a book!

  • @LambdaJack
    @LambdaJack Год назад +1

    Almost C++.

  • @Jaime.02
    @Jaime.02 Год назад +3

    gang 🤙discord

    • @bereck7735
      @bereck7735 Год назад

      Hello mithic

    • @Jaime.02
      @Jaime.02 Год назад

      @@bereck7735 i'm not mithic xD

    • @bereck7735
      @bereck7735 Год назад

      ​@@Jaime.02 oh my bad, your pgp kinda reminded me of him.

  • @anon_y_mousse
    @anon_y_mousse Год назад +2

    Did you copy the python executable into your PyCharm projects folder? Does it not respect the PATH variable or are you just being weird?

    • @mCoding
      @mCoding  Год назад +4

      As is standard industry practice, I use virtual environments so that my different Python projects with different dependency requirements do not affect each other. See docs.python.org/3/library/venv.html for more information about virtual environments.

  • @SkyFly19853
    @SkyFly19853 Год назад

    Pythonformers... Here they come... 🤔😏

  • @scopedealer
    @scopedealer Год назад +2

    Can someone pls help me? Just reply to this comment. So I'm only 11 and I just got the python book and I'm learning if statements and I've made it all but I don't know how to run it or whatever for example, if a made a code looking like this: if mood == tired
    Hit_snooze_button = true and then I do print (Bob is tired. He hits the snooze button.) And then u press enter and nothing happens, it doesn't say correct or incorrect, it doesn't even give me a error or anything. So can anyone help me with this pls?

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 Год назад

      Try Jupyter. It’s probably the easiest way to learn Python.

    • @scopedealer
      @scopedealer Год назад +1

      @@lawrencedoliveiro9104 ok I'll try it thank you

    • @NostraDavid2
      @NostraDavid2 Год назад +1

      If you're already using vscode, add a line with "# %%" to a .py file to create a jupyter cell in text more. I like that more then creating a jupyter notebook.
      The you can use shift-enter and ctrl-enter to run a cell (just experiment with it)

    • @lawrencedoliveiro9104
      @lawrencedoliveiro9104 Год назад

      @@scopedealer And don’t accept poor substitutes.

  • @naghs2726
    @naghs2726 Год назад

    when i started coding I loved your python videos but now that ive learned more languages i wish you would do videos on more of them instead of just python like C++ and Java

  • @p_square
    @p_square Год назад

    discord gang but late

  • @bunchofcells3333
    @bunchofcells3333 Год назад +1

    Discord Gang

  • @fuexfollets5755
    @fuexfollets5755 Год назад

    Discord gang

  • @lior_haddad
    @lior_haddad Год назад

    🤔

  • @i007c
    @i007c Год назад

    969 LOL :)))

  • @noahcollin9532
    @noahcollin9532 Год назад +5

    Coming from C#, it baffles me that getters and setters aren't used more in python

    • @kdaubtf2
      @kdaubtf2 Год назад +9

      Disgusting boilerplate 🤮

    • @__mrmino__
      @__mrmino__ Год назад +1

      Why would you want them? What purpose does a getter on a simple instance field serve?

    • @noahcollin9532
      @noahcollin9532 Год назад

      @@__mrmino__ for getters in particular in python, I'd imagine it's useful in teams. A get method could return all customer information except payment, unless it's coming from a paymentInfo class instance. So only certain objects could get certain attributes. And one coder can be assured that other classes don't get information they shouldn't. I'm honestly not working in production python, so I don't know how, if at all, they're used in industry. But it's a central tenant of C# on top of public and private objects and classes.

    • @__mrmino__
      @__mrmino__ Год назад +5

      @@noahcollin9532 you just described one of the usecases of @property :).

    • @noahcollin9532
      @noahcollin9532 Год назад +3

      @@__mrmino__ wow I've learned something from a RUclips comment. I thought the comments section was only a place to scream into the void. Thanks!

  • @markcuello5
    @markcuello5 Год назад

    HELP

  • @timseguine2
    @timseguine2 Год назад

    Double dunder dict? I hardly know her

  • @hanabimock5193
    @hanabimock5193 Год назад

    All this weird stuff just to achieve what a typed compiled language already achieves way faster, way simpler. Python is great for prototyping but if you need to do stuff performant and handle abstraction better, just use something else.

  • @vaulttectradingco8438
    @vaulttectradingco8438 Год назад

    Discord Gang

  • @markcuello5
    @markcuello5 Год назад

    HELP

  • @lunarmagpie4305
    @lunarmagpie4305 Год назад

    Discord Gang