We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

It's not magic: descriptors exposed

00:00

Formal Metadata

Title
It's not magic: descriptors exposed
Title of Series
Part Number
21
Number of Parts
169
Author
License
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
Facundo Batista - It's not magic: descriptors exposed This talk shows the Python Descriptors, detailing their behaviour with a detailed practical example, so we can understand the power and flexibility they give. As a bonus track, class decorators are explained. ----- This talk presents, using a detailed practical example, the Python Descriptos. The behaviour of descriptors mechanisms is detailed, showing their power and flexibility. Finally, as a bonus track and to complete the used practical example, class descriptors are explained.
11
52
79
Multiplication signVideo gamePerfect groupPresentation of a groupLecture/Conference
Presentation of a groupTheoryWhiteboardGame theoryMoving averageAuthorizationLevel (video gaming)Physical systemMeta element
Social classClique-widthLengthGame theoryWhiteboardGroup actionPhysical systemSocial classWave packetComputer animation
Social classClique-widthLengthNetwork topologyWritingMechanism designTwitterLecture/ConferenceComputer animation
Network topologyArithmetic meanHypermediaMusical ensembleMatching (graph theory)Lecture/ConferenceComputer animation
Group actionNumberPoint (geometry)Lecture/ConferenceComputer animation
Group actionSocial classMatching (graph theory)TheoryCodeLecture/ConferenceComputer animation
Keyboard shortcutAttribute grammarCommunications protocolObject (grammar)Game theoryWhiteboardTheoryAttribute grammarKeyboard shortcutCommunications protocolScripting languageSource codeComputer animation
Control flowObject (grammar)Set (mathematics)Attribute grammarCodeWordSet (mathematics)Multiplication signGame controllerWordObject (grammar)Normal (geometry)Attribute grammarComputer animation
Control flowObject (grammar)Attribute grammarSet (mathematics)CodeWordAmsterdam Ordnance DatumForm (programming)Social classInstance (computer science)Object (grammar)Normal (geometry)CodeData miningSocial classCASE <Informatik>Scripting languageMoment (mathematics)Attribute grammarLecture/ConferenceComputer animation
Social classInstance (computer science)Attribute grammarMultiplication signAttribute grammarSocial classSlide ruleMereologyEuler anglesCellular automatonTask (computing)CodeLecture/ConferenceComputer animation
Social classInstance (computer science)Attribute grammarAttribute grammarSocial classInstance (computer science)FrequencySoftware testingCodeProof theoryMoment (mathematics)CASE <Informatik>Lecture/ConferenceComputer animation
Social classInstance (computer science)Attribute grammarImplementationTheoryAttribute grammarMoment (mathematics)Set (mathematics)Social classScripting languageLecture/ConferenceComputer animation
Social classInstance (computer science)Attribute grammarImplementationScripting languageInferenceCharacteristic polynomialSocial classInstance (computer science)Multiplication signSet (mathematics)UnicastingverfahrenCodeAttribute grammarLecture/ConferenceComputer animation
Social classInstance (computer science)Set (mathematics)Social classInstance (computer science)View (database)AreaMoment (mathematics)CASE <Informatik>Population densityData dictionaryDisk read-and-write headInformationIdentifiabilityEqualiser (mathematics)Web pageDegree (graph theory)Information retrievalData storage deviceDefault (computer science)Lecture/ConferenceComputer animation
Social classInstance (computer science)Type theoryData storage deviceAttribute grammarInstance (computer science)Type theoryDifferent (Kate Ryan album)Group actionSocial classCASE <Informatik>Subject indexingComputer animationLecture/ConferenceUML
Social classType theoryCASE <Informatik>Moment (mathematics)Game theoryDifferent (Kate Ryan album)Attribute grammarLecture/ConferenceComputer animation
Social classType theoryInstance (computer science)Point (geometry)Set (mathematics)Different (Kate Ryan album)CASE <Informatik>Lecture/ConferenceComputer animation
CASE <Informatik>Set (mathematics)Scripting languageLecture/Conference
Social classType theoryInstance (computer science)Attribute grammarImplementationComplete metric spaceCASE <Informatik>Sampling (statistics)Complete metric spaceEndliche ModelltheorieAttribute grammarCodeNormal (geometry)Computer animation
Category of beingComputer programmingCategory of beingPoint (geometry)BlogService (economics)TheoryLecture/ConferenceComputer animation
Social classNumberGame controllerRight angleStaff (military)Attribute grammarSocial classLecture/ConferenceComputer animation
Social classInstance (computer science)Social classCellular automatonCASE <Informatik>WhiteboardMultiplication signScripting languageLecture/ConferenceComputer animation
Social classInstance (computer science)Set (mathematics)Social classClassical physicsInstance (computer science)Data storage deviceLecture/ConferenceComputer animation
Social classInstance (computer science)Clique-widthLengthAttribute grammarNumberInstance (computer science)MereologyCASE <Informatik>Physical systemSocial classNumberString (computer science)Lecture/ConferenceComputer animation
Social classClique-widthLengthAttribute grammarNumberSocial classScripting languageAttribute grammarSummierbarkeitNumberBounded variationLecture/ConferenceComputer animation
Right angleFunction (mathematics)Social classMountain pass3 (number)Endliche ModelltheorieForm (programming)Field (computer science)Point (geometry)Video gameCASE <Informatik>Instance (computer science)Level (video gaming)Attribute grammarAngleFunctional (mathematics)Declarative programmingSocial classEndliche ModelltheorieType theoryCasting (performing arts)WordScripting languageRight angleMassComputer animation
TrailMenu (computing)Social classFunction (mathematics)Multiplication signTrailWhiteboardGame theorySocial classCodeSoftware testingCategory of beingFunctional (mathematics)Operator (mathematics)Lecture/ConferenceComputer animationDiagram
Social classFunction (mathematics)Normal (geometry)Mountain passGlass floatDegree (graph theory)Social classFunctional (mathematics)Casting (performing arts)1 (number)Game theoryCodeWhiteboardEqualiser (mathematics)Computer animation
Social classGlass floatInstance (computer science)Social classNumberDampingFunctional (mathematics)Data dictionaryType theoryAttribute grammarBit rateDataflowDisk read-and-write headComputer animation
Social classUniform boundedness principleQuicksortPoint (geometry)Physical systemScripting languageSocial classCodeGame theoryWhiteboardComputer animationLecture/Conference
Normal (geometry)Type theoryInternetworkingGrand Unified TheoryLatent heatCASE <Informatik>Message passingView (database)Scripting languageInstance (computer science)Different (Kate Ryan album)Social classCodePresentation of a groupLecture/ConferenceComputer animation
Special unitary groupArithmetic meanLine (geometry)SummierbarkeitLevel (video gaming)Maxima and minimaMetropolitan area networkScalable Coherent InterfaceRankingRaw image formatAverageTerm (mathematics)Bargaining problemHypermediaMoment of inertiaCache (computing)Computer fileComputer-generated imagerySlide rulePresentation of a groupSystem callWeb 2.0CodeComputer animation
Slide ruleComputer programmingExterior algebraRight angleInsertion lossLecture/ConferenceComputer animation
Functional (mathematics)CodeSystem callLecture/Conference
Social classFunctional (mathematics)Arithmetic meanCASE <Informatik>Point (geometry)CodeSystem callMereologyScripting languageCartesian coordinate systemLecture/ConferenceComputer animation
Social classGlass floatMereologyDataflowMoment (mathematics)Right angleSocial classInsertion lossType theoryMultiplication signComputer animationLecture/Conference
Form (programming)Presentation of a groupSlide ruleMultiplication signSocial classFaculty (division)Lecture/Conference
Social classForm (programming)Social classInstance (computer science)Series (mathematics)Casting (performing arts)Right angleTheoryWordCoefficient of determinationGame theoryWhiteboardLecture/ConferenceComputer animation
Social classNormal (geometry)Mountain passPoint (geometry)Dew pointRight angleFunction (mathematics)Video gameSet (mathematics)Lecture/ConferenceComputer animation
Social classInstance (computer science)NumberCASE <Informatik>Instance (computer science)Right angleComputer animationLecture/Conference
Social classInstance (computer science)Set (mathematics)Instance (computer science)AreaInheritance (object-oriented programming)CASE <Informatik>Category of beingSocial classProper mapCodeComputer animationLecture/Conference
LengthSocial classClique-widthAttribute grammarNumberCrash (computing)Inheritance (object-oriented programming)CASE <Informatik>Social classMultiplication signProduct (business)Machine visionPersonal digital assistantGame theoryWhiteboardCodeLecture/ConferenceComputer animationMeeting/Interview
LengthSocial classClique-widthAttribute grammarNumberInstance (computer science)Data dictionaryInstance (computer science)FrequencyCASE <Informatik>Scripting languageAttribute grammarComputer animationLecture/Conference
Social classInstance (computer science)Instance (computer science)NumberSoftware bugCASE <Informatik>Key (cryptography)Message passingLecture/ConferenceComputer animation
Social classInstance (computer science)Instance (computer science)Data dictionaryKey (cryptography)DatabaseSocial classSlide ruleRun time (program lifecycle phase)Computer animationLecture/Conference
Social classClique-widthLengthAttribute grammarNumberSocial classConstructor (object-oriented programming)Computer animation
Social classClique-widthLengthAttribute grammarNumberEqualiser (mathematics)Moment (mathematics)Social classAttribute grammarComputer animation
Lecture/Conference
Transcript: English(auto-generated)
And Pacundo Batista will be telling us about Python descriptors. There will be some time for questions at the end. So hang on to that, and I'll come around with microphones at the end. Thank you very much. Do you hear me OK? Yes. Perfect. OK.
Welcome. Thanks to be here. Thanks for the advantage of putting together this awesome conference. I will be talking about descriptors, just trying to everybody understand a little descriptor. Descriptor is a hard topic.
Normally, the 50 times that I saw presentations about descriptors until I understood it is a lot of theory. And you get out of the presentation saying, OK, I kind of understand the theory, but I don't have a clue how to apply that. So we talked at this talking that is
the other author of this talk. We decided to do it backwards. So we like games, board games, and roll games. And we decided that as we are now at level two, we not only wanted to play board games,
but to create them, to design a system where you can create board games. So it's like playing the game. It's like a meta play. So we wanted not only to create the system, but we wanted to offer other people ways
to create board games. And we wanted to offer them a possibility of creating board games in a simple way, in a useful way. So we wanted to do something like this. We wanted to have powers and characters. The powers is where you encapsulate
what the powers can do. So for example, you have a strength that is a useful power for a character. And if you have a strength, you can break walls, or you can jump a hole, et cetera. If you have magic, you can do a spell, et cetera.
See that it's very simple to find the power. It's just a class. It's just what you can do. And the action itself is a method that, of course, according to some values, you have more or less magic, et cetera, you can do it or not. And when you define a character, you just define what powers this character has.
So this is very simple written. If you write it like this, it will not work. But we wanted to do this, and we wanted to go from here. So this is how we'll use this very simple mechanism.
For example, you instantiate a character that is Gimli. Gimli, you can instantiate it with a lot of strength, and see how you can check if Gimli can break a wall. You ask for the strength of Gimli,
what the power can do. Also, you can modify very easily the value of that power. See that how I directly modify that power in Gimli. So if I put more power to Gimli, for example,
it will be able to break the wall. Or for example, this is a character that has both powers. So it has a power with some strength and has some magic.
And if it's okay, Gandalf can charm a tree, it's okay, but Gandalf cannot fight Saruman, but I can just put more magic in Gandalf. From that point, Gandalf the White will be able to fight Saruman. The idea is that we wanted to present,
we wanted to give the powers in the characters in a very simple way to manipulate, working with them like numbers. So you can get or you can set the powers in the character, but also encapsulating
what the power will be able to do in that very same class where you define the power. So it's very weird way of doing things, but it's very simple. So how we did this?
I mean, we didn't do it with magic. I mean, this is not magic. It's just we used descriptors to make that code work. So the idea here is that we will go now a little into the theory of the descriptors and then we go back to the board game
and see how we did apply that theory. So this is the last chance. If you want to see descriptors, you stay. So a descriptor in general is an attribute with binding behavior, one whose attribute access
has been overridden by methods in the descriptor protocol. Very, very simple, right? It's very understandable. I mean, you already know how it works. The idea is to see what we really are doing here in more simple words. The idea behind the descriptors is that
you take control of some normal Python behavior. Every time you do a set of an attribute in some object, every time you get some attribute from some object or every time you remove some attribute in some object,
with descriptors, you get the possibility to execute your own code instead of normal Python behavior. So when I do some object.attribute equal 42 in that case,
it's not Python just assigning the value 42 to the attribute in this object, but instead, if I'm working with descriptors, some code of mine is being executed in that moment. How is that?
You define descriptor with classes. For a class, to be a descriptor, it has to have some special methods. In this case, we have a dundergate. The dundergate makes this class a descriptor.
This dundergate will be executed every time you access the attribute. So let's see it in real code. In the upper part, I have the very same class
that the last slide where I have a dundergate and that dundergate just return hello world. Then I define another class that is the class where I use the descriptor and see that x is a class attribute that is very important
because descriptor magic is activated when you are using it. You are using the descriptor as a class attribute. X is a class attribute that has an instance of that hello world descriptor. Then I instantiate any class and the moment that I do ac.x,
the moment that I'm accessing that attribute, my own code is being executed. So this is the proof that with descriptors, I can get in the middle of the Python execution for this case.
So far, how are you doing? It's totally crazy, makes sense. I already lost you. It works. You see how this magic happens.
We have another special method for descriptors. We have the dunder set. The dunder set is executed the moment I set the attribute that when the attribute is the class descriptor. This is very similar than before. I have my descriptor that is a normal class,
but as it has the dunder set, it's a descriptor. I use that descriptor in a class attribute in another class. And then when I set that attribute, my own code there will be called.
See that, I didn't mention that. For example, in the dunder get, I receive the instance of the class and the class that that instance belongs. It sometimes uses for some clever tricks.
The class there is not normally used. In the set, it's different. In the set, I receive the instance that is AC and the value that I'm setting. So I also receive this BLE.
Okay, let's see both working at the same time. This is an example code, just to see the descriptor that has both methods, dunder get and dunder set. See that the dunder get and dunder set, what they do.
The dunder set receives a value and just store that value in the instance dictionary. Okay. And the dunder get retrieves that value with a default in case it's not there yet
and just return a greeting. Let's use it in the second column. I define a new class, hello world two, that has a class attribute, again a class attribute, that is agreed with an instance of this healer.
I instance healer world two and if I access, if I do healer.grid, that dunder get will be executed. That will return hello unknown because the instance still doesn't have the who set. The moment I do healer.grid equals something,
the dunder set is executed and in this case I put that information in the instance and when I access the attribute again, it just restore it and use it.
Okay, yes or no? Okay, we have two types of descriptors. We have overriding descriptors and non-overriding descriptors.
This is where confusion start to flourish but don't worry, it's very simple. They are just classified into groups because the behavior is a little different. Where the behavior is different? Here. In the first column in the left,
we have an overriding descriptor. See that we have a class that has both dunder get and dunder set methods. In this case, I use the descriptor here. When I do c.d, it executes the get
and when I do c.d equals something, I execute the set. This is very similar to what we saw before. More than very similar, it's the same. In the case of non-overriding descriptors, we do not have a set method.
The difference of not having a set method is that when I use the descriptor, if I do a c.d, of course, it execute the get but the moment I do c.d equals something,
the attribute d of the instance, c is overwritten by this value. So from this point on, c.d is one to three. It's no longer the descriptor. In this case, I execute this dunder set
and from this point on, c.d is still the descriptor. This is the only difference. You have to be careful when you write your own descriptors because even if you don't want to put
any special behavior in the set, you need to be careful that if you don't specify a dunder set in your descriptor, it may be overwritten. Of course, it's a behavior that you may want to use.
We will see a very common case where that behavior of non-overriding descriptor is used by you normally. Okay, just for completeness, we have another
special method that is dunder del that as you may imagine, it specify code that is executed when you delete an attribute.
So in this case, when you do del ac.x, you override the normal Python behavior of removing that attribute, but you just execute some code of yours. Okay, one note here because when I present these examples,
you say, oh my god, yes, you can do whatever you want with properties instead of using descriptors manually. Yes, you can do, but the point of the talk is to talk about descriptors. I cannot make the examples too complicated, et cetera.
So let's go back to wizards and dwarves and see how we use this descriptor theory in the practice. Remember this, that we have the idea of having powers which encapsulate what the power can do
and the character defining the powers as class attributes and then being able to just instantiate the character, try to see if the character can do some stuff
asking through the power that the character has, but also modifying the values of the powers like simple numbers. This of course doesn't work if you just write this because some magic, we need to add some magic here.
How we make this work? Okay, we make this work not only using descriptors but also class decorators.
So the idea behind all the magic is that we have this power descriptor. This is the first time I presented a descriptor for the wizards and dwarves case. This is the only descriptor that we have. This descriptor that has Dunder set and Dunder get,
when you instantiate it, you get the name of the power and the class of the power. So it can be magic and the class magic for the power you define. And the only thing that it does is just store
in the instance dictionary, very similar to the other example, it just store the instance of the power class that it received with the value that it received and in the case of the Dunder get, it just retrieves that.
How we make to this power descriptor to be used by the other parts of the system? We have two class decorator. We have this at power that gets this very simple power class that you wrote
and makes two things. For one, on one hand, it registers strength or magic as a power, but also makes that these classes behave like numbers.
And then we have another class decorator that is character that grabs the character you wrote and for the class attributes that you specify there, automatically converts them to be descriptors
because there, you just put class descriptors, sorry, there you just put class attribute, but these are not descriptors, so it automatically converts them.
Before going into more detail of the code, let's see other cases where the descriptors are used in real life. So Python methods is the most normal case of using descriptors.
When you define a method, what is a method really? What is a def there? It's a function, right? And the function there, where is the finite function in the class? So, metal is a kind of class attribute
and this works like a descriptor. The descriptor gets in, does this magic, so when you call foo.metal one, two, a special descriptor is executed
that calls the function, you define it, adding a self in the front. So the magic of automatically inserting a self when you call in a metal is done by descriptors.
And these are non-data descriptors. So, if you have an instance foo and you do foo.metal equals something, you override that name. Remember that we have two types of descriptors,
and if you had under get and under set, the descriptor was executed, and if you only had under get, when you set the attribute, you lost the original descriptors. Metals works like that. If you set a name or something
with the name of the metal, you lose the metal in an instance. Python works like that. So, the angle, most of the magic in models declaration of the angle is done by descriptors. The very same way that I put the powers
in the characters before. You just specify stuff at the class level and it works. How does this work? They are descriptors. Do you ever use slots?
Slots also work through descriptors with a very detail that is not implemented in Python really but it uses the descriptors API directly from C, but it also uses descriptors, the concept. How are we going with the time?
Okay. So, we have time for the bonus track. That is where we get into the class decorator and the detail of the code to make that game board work. Before going into the detail of the code,
I wanted to present a little about class decorator because it's not a common topic. Class decorator, I don't know if you ever heard about, raise your hands if you ever see a class decorator before. Awesome. And raise your hand if you saw a normal decorator before.
So, this is very simple. A class decorator is a function that receives a class and returns a class. It is the same that the function decorator but for classes. It's the same concept. If you have a definition of class foo, whatever,
foo is the class with the final. But if we have a class definition with the decorator, foo is not what defines it. Foo is the class returned by that decorator which receives the class with that with the final and does whatever it wants with it.
It's the same than doing foo equal decorator foo. The very same thing that function decorators. So, how did we use it in the board game? This is the class decorator that I mentioned before
that you just put it in the very simple power class that you define and makes it magic. See what it does. This code is not really simple but we can make it understandable. The power receives a class. The class is this one that we are defining.
And the power decorator creates another class, a new class with a type function that inherits this very class but also inherits float. And this is how the behavior of a number
is inserted to the power. And also registers that class name in a global dictionary that will be used later to retrieve it.
Also, we have another class decorator that was character that we applied when we defined characters. Character, the class decorator just gets the registered powers.
And if we have a class attribute in the class that it received that has the same name of a registered power like strength or magic in this example,
it replaces it. It replaces it, see that setter, it replaces it with a descriptor that is our power descriptor. That is the only descriptor that we use in this system. It replaces it with that power descriptor that holds the name of the power
and the class of the power. This is how you are able to write this very simple code to make the board game without even noticing that the descriptors works in the back.
Okay, that's all. It wasn't that hard. The concept that I want for you to take here is that descriptors allows you to get into the normal Python behavior when you get an attribute, when you set an attribute,
and when you delete an attribute, that you have two types of descriptors. Those two types of descriptors, the difference is that in one case, when you set an attribute, the code of the descriptor is executed, and in the other type of class descriptors,
when you set the attribute, the descriptor is removed from the instance, overwritten. And also the idea that I want for you to take from here is that it's not deep magic
that, okay, maybe it's useful for me to understand because I may hit some code some when, and I need to understand it, but that is something that you can really use in the cases that you want to get in the middle of the code. So take it in mind,
and when you need to solve some specific stuff, descriptors may be useful for you. In this very presentation that is already published in the web, you can see the code, you can see it unless you have a telescope or something,
but there is all the code for making everything work, so if you're interested, go paste that into a couple of .py and start to play. Some legal stuff, because, I don't know, maybe Michael Jordan didn't say what I said I did say,
but, and that's all. Thank you. Liza here, and if you have any question, I'm very glad to not answer them.
I find this descriptor thing quite appealing because it's like an alternative to when you have to do metaprogramming to insert things and stuff like that,
but I'm wondering how is it to debug? How hard is it compared to metaprogramming or doing everything more plain Python? It's not hard to debug at all because you have to think it like
you are doing funny function calls. I mean, you have a code like this,
you have a code like this, and the only thing that you need to take in consideration that in the case, for example, of doing gimly.strength equal whatever,
you are doing a function call at that point, so when you read your code and you know that you're accessing a descriptor, you know that in that case, you're getting to jumping to that part of the code,
and that's all. The moment you understand that, you can easily follow the flow of the execution. So when you are doing the, well, I was more referring to the last part where you actually use a type to create a class insert in the methods, so I was more referring to debugging that part.
It just worked. I didn't have to debug it, really. It just worked. Actually, when we created the presentation, it was three times more complex everything.
We found the way to make it simple like this. I think it's not simple, but it does what it needs to do. Can you go to the next slide when there's a character? I think, in this one, looks like he's looking at the name of the attribute,
not the actual class. So if I call, if in the class character, I call something strength, but then I do equal to, there's nothing to do with the actual, what happens. This, yes, if you misspell this, you, it will fail. You could check for the instance and the class name,
and it will be more robust. So you should check in theory on the right and not on the left to be more sure of what you're doing because it can, I don't know. You could. It will be better. This works.
I mean, this whole board game thing, whatever, it's just an excuse for the talk. We really didn't do this for real, but it's just an excuse to use the scripter somewhere. Okay, sorry, another question. Is there a reason to use a dunder dict, underscore dict, in the get and set before
in the other slides, and not set utter, for example, because, is it because you can't use it there maybe, or? Sorry, when, where? In the dunder get and dunder set before. It's accessing the scripter. In the power descriptor.
Here. Yeah, why not doing set utter there? Does it work maybe, or? I don't remember now, but I think there is a case where it doesn't work.
I don't remember why. Ah, right. Right, if you access, if you do instance dot, or, well, set utter instance name and the value, it will be calling the descriptor itself.
So you don't set the attribute, it's just mess with the dict. Okay, so how do you deal with inheritance when using class descriptors? Well, that's a very, this is an interesting question because this is one case where you cannot use properties
because, I mean, you are encapsulating code and you want to use inheritance, so you cannot use property anymore. You need to use proper descriptors. You just use it. It just works. There is no magic there.
You can have parent classes with the other methods or whatever, and the descriptor inherits, and it works. So basically you have to put class decorator in both parent and child class, but in that case, it will. Ah, you say not one created the decorator, but when you see it in this case?
No, in class decorators for character, for example. It does some magic with applying a power descriptor. Right, I don't know. In that case, I don't know if I didn't try it. I mean, it's, I remember, this whole board game,
power, character, whatever, it's just an excuse for the presentation. We didn't use it in production or anything. So I would need to follow the code now. I didn't try it. There is another one here. In the previous slide, here, with the power decorator,
is there any reason why you are setting the value into the instance dictionary and not into the power descriptor instance itself? Yes, because the power descriptor will use,
will maybe apply to different instances. So it's a normal behavior, maybe not in this case, but you may have the descriptor instance to be applied to different attributes. So you normally start the stuff into the instance. It's what you normally see and everybody does.
But what if another descriptor wants to instance, wants to access the same key in the instance dictionary? It doesn't happen in this case. If you have that case, you can start it whatever you want. Okay, thank you. I mean, there is no Python magic here.
You just put stuff in some places and then use it. I mean, you could have a global dictionary with the key being the instance and the name and access that global dictionary instead of storing stuff in the instance. You can pick it, you can send it to the database.
But it's pretty normal for the descriptors to mess with the instance dict. Yeah, great talk, thank you. I have a question. Can you explain more why we are initializing the descriptors inside the class
and not, for example, in the dunder init? And can we change the descriptor during the run time? Not on this slide, the previous one, for example. Yeah, here on the class, you initialize strength and magic inside the class
and not in the dunder init. I'm initializing it. The construction of the strength and magic. The what? The construction. There, the instantiation. Yeah, why? Because it needs to be a class descriptor. If it's not a class descriptor,
it doesn't work like a descriptor. Sorry, sorry. If it's not a class attribute, it doesn't work like a descriptor. The magic of have a class, having it or set and being a descriptor is only executed
when that is a class attribute. So also see here that in the moment of instantiation, I'm doing self dot strength equal strength and also at this very same moment, I'm executing the descriptor's code.
Thank you, I think that's the last of our questions. Okay. Everyone have a very nice lunch. Thank you very much.