The Functools Module

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everybody uh welcome to this webinar organized by jetbrains um i'm your host nafio islam today uh we have a really special uh guest today mike driscoll mike has been writing python books for a very long time and has been a part of the python community for a long time he's currently a software engineer at pluralsight and he's going to be giving us a talk on the funk tools module something very near and dear to my heart because there's so many cool things that you can do with it so before we get started on this i just wanted to let you all know that if you have any questions you can um over here or here yeah they're over there there are you can ask questions in the chat and we'll be monitoring that um as well as on twitch apparently we're live there too so if you have any questions we'll be able to see those as well um so another thing that people ask us is is this uh session going to be recorded uh the answer is yes um it will be recorded and it will be available immediately after um this uh webinar is over so without much further ado uh please welcome mike driscoll hello i'm mike and as uh rafael said i'm going to talk about the funk tools module a really amazing module in python all right just a little bit about me i write about python at mouse versus python as mentioned i'm a book writer i have 10 books out right now most of which are self-published real python lets me contribute to their website from time to time so i have a couple articles on there and i just wanted to talk a little bit about content creation because it's my passion and i like to write about python wherever i can and so i've been doing a lot of that on twitter and linkedin and of course on these other websites and i've been slowly adding neat anita tutorials to my youtube channel anyway enough about me let's talk about python python has over 200 modules it's awesome and because it comes with so many modules you can do most things out of the box with python today we are going to talk about the funk tools module it's got kind of a weird name so let's figure out what is functuals to begin with the funct tools module is a collection of high order functions functions that act on or return other functions so what that means is that most of functools are decorators because a decorator by definition takes in another function and returns a different function usually without modifying um the function that is decorated in general any callable object can be treated as a function for the purposes of the functoil's module all right the functions module has a bunch of different little items in it we're going to try to cover most of them it actually has three three items in the cashing category cash cash property and lru cash another interesting tool in func tools is total ordering we're going to talk about partial reduce single dispatch and wraps as well um i think you're going to find this really interesting i know i always have fun playing with this with this module all right let's start with caching so uh for to me 3.9 isn't that long ago and so i just want to mention you know when did when did all this get added so cash is kind of new came out in 3.9 for in python cash property came out in 3.8 and basically let you add cashing to your properties and then you have lru cash which has been around basically for as long as funk tools has been around way back in python two days let's talk about funktools.cache though so funktools.cache has a simple lightweight unbounded function cache sometimes called memowise now this comes directly from the python documentation so it's a little bit rough around the edges and i'll try to explain you know what this all means but basically what funktools.cache does is it's kind of a shortcut way of saying lru cache with a mac size of none this creates a thin wrapper around a dictionary lookup of the function arguments because it never needs to evict or remove old values functuals.cache is smaller and faster than just using lru cache with a size limit sometimes i think this is a lot easier to understand if you actually see an example so we're going to look at python an example from the python docs okay so to get access to the cache you do from funk tools import cache apply the decorator to whatever function you want to add a cache to in this case i'm going to add it to this recursive factorial function and then i'm just going to kind of walk through what's happening here because it's kind of hard to show in this code what's going on so if you call the factorial with the number 10 and what this means is it's going to be like 10 times 9 times 8 times 7 times 6 all the way down to to 1 is what it's going to do basically the first time you call it there is no cash so um this one this first time you call factorial is going to be kind of slow so it's going to make a bunch of calls and none of it's going to be cached but the next time you call it you're going to call it with factorial 5 and it's going to just return that value immediately because it's cached and if you call a value that's above the cache version it's just going to make five new recursive calls because it already has the first 10 cached so factorial 15 will run many many times faster than factorial 10 did all right let's try some other code just to kind of nail this home first i want to show you what happens when you don't have a cache at all and we're going to use python's time it module to time how long it takes to run this fibonacci is a pretty common programming problem that a lot of people like to talk about especially beginners and it's a nice recursive function and it takes a little bit of time to run so this is just doing fibonacci we're going to pass in 35 as a fibonacci number that it's going to try to calculate for us and time it we'll figure out how long this takes to run so let's go in here and go to run it's going to take a little bit while it thinks about it i think it'll take around four seconds yeah 4.49 seconds to run this code that's not great let's see if we can speed that up by adding a cache to add a cache all you have to do is do from funk tools import cache add the add cache to decorator and then just rerun the code let's see what kind of speed up we get by re-running it remember the first time we ran it without a cache it took 4.49 seconds as you can see that number dropped dramatically now we're at point zero zero zero zero two two seconds to run the same bit of code because we added a cache that's amazing you can speed up your code really quickly locally by using a cache all right let's talk about functools.oru cache which is very similar let's switch back over here grab our lru cache example this example is more interesting to me because instead of just doing a recursive function we're going to try downloading web pages from the python documentation url so here i'm going to use import time instead of time it what is the kind of time how long it takes to download stuff we use the url lib module to download the html pages and then we have this little function here get webpage so the web page it has a url in it and i just slap in whatever modules code i want to grab and then down here we will try to read it and return it as basically text if i happen to mess up with my module name we'll get an error and return none up here we have llu cache with our max size of 24 what that means is that the cash will save 24 calls um to get paid get web page if you get to the 25th call of get webpage an item the first item will be dr popped out of the cache to make room for the new one uh the main reason you want to have a size limit is you know all this stuff gets cached in memory so you wouldn't want to like download all 200 plus modules into memory unless you have a lot of memory for example although i think most computers nowadays wouldn't have any problem with that unless you have too many tabs open in in chrome of course all right so down here to run the mod to run this code i just do together some examples we're going to loop over func tools os sys and os a second time the reason os is in there twice so i want to see what happens when i try to call or download that module the second time that should activate the cache and we should see that it gets returned pretty much immediately so to time this we'll just loop over the modules for module and modules start the time and the time and then calculate how many seconds it took to download that particular module's html text let's go in here and give it a run yeah i get this sometimes i'm not sure why it does that i think the website that i'm connecting to has an issue let's try that one more time there we go so the first time through funk tools is .229 module is 0.32 so it's obviously a little bit bigger than funk tools of course os module has a lot more data a lot more functions and methods than func tools does this module is actually smaller at 0.25 and then when we call the os module a second time you can see that it basically returns immediately point zero let's see one two three six six zeros that's a that's a infinitesimally small number so you know it's faster than the blink of an eye it just returns that fast um i would highly recommend and this is something i haven't tried yet but it'd be really fun to put 26 items into this list and just see how the cache changes over time and you know maybe just put in even os module in there a bunch of times and just see how it changes um when in its runtime anyway all right let's talk about our next topic functools.totalordering this one is one i don't use a lot and i don't think a lot of people use it maybe because they don't know it exists but basically given a class defining one or more rich comparison ordering methods and by rich comparison ordering methods that's a special dunder method which we're going to get to in a second this class decorator will supply the rest it simplifies the effort involved in specifying all of the possible rich comparison operations so let's talk about some of those um the class must define one of the following four dunder methods dunder lt for less than dunder le which is less than or equal to under gt for greater than and then ge is greater than or equal to so you can define one of these and you also must define that eq or equals dunder method and then you can apply the total ordering code um to your your class and it'll supply the rest so how do we uh see that in action i thought about this a little bit and decided let's just write some code that doesn't use funk tools at all so just for fun i created a number class it has an init ender which passes in whatever number i get i just set it up in there and then i just defined a couple of of the dunder methods so we do less than and return if that value is less than the other value and we also do an equals thing and just for fun of it i'm messing this up i'm just making it do the opposite of what it's supposed to do normally when you define this method you would do equal equal so you know play with that if you want um i'm actually going to leave at equal equal so it's less confusing all right so x equals 5 y equals 10 of my special number class and then i'm just going to try to compare them and you'll note that i'm calling gender methods that don't exist in my class so let's see what happens when i run this code and see if i just get an error or something else okay so let's match this up the first one less than is true because we actually have it implemented and it's comparing the values correctly less than or equal to is not implemented neither is greater than or greater than or equal to and the eq one returns false because obviously five and ten are different so rather than adding all the boilerplate for the other dunder methods in year we can just use total ordering so to use total ordering you do foam func tools import total order ordering and we apply it to the class itself whereas with the cache for stuff the cache decorator we applied those to functions here we're applying this decorator to the class otherwise the code remains the same so now when we run it we should see that all of the other comparison operator or comparison uh special methods work because now we have less than or equal to greater than g saying true true false false true the way that they should whereas before we had not implemented because obviously we hadn't implemented them so this is kind of a shortcut i think i've heard some people say this is kind of slower than implementing it yourself like when you run the code but it reduces uh development time so there are trade-offs just something for you to play with i haven't actually timed it to see if it actually is slower to use this or not though so i don't know if that's just someone who likes to complain or if it's actually true all right let's move on to partial functions it's just like i'm thirsty all right so partial function is kind of like a lambda in a way they're used for creating new functions with defaults applied i have an article about it on my blog at mouse versus python and i'm sure real python has covered this as well anyway let's look at an example because i find partial examples partial code examples hard to explain without actually looking at the code so to use it you import partial and you'll note that this time we're not going to decorate a function we're actually going to call it but in much the same way as a decorator takes a function partial also takes a function so the first argument to partial is whatever function you want to turn into a partial function and then you can basically set defaults for different arguments within that function so p add is now a function that's a partial function and every time you call it with a value it's going to take that value plus what it plus the default so let's see you will run this it prints out seven and four as eleven and just makes you know it's kind of a shortcut way of just running a function in a special way to me this doesn't look real obvious why would i even use this um i've used it successfully when in gui programming so you know stuff can be used partial can be used as a callback anticancer for example so let's just take a quick look at that here's an example of some tkinter code tkinter being a graphical user interface for python tkinter comes with python so you shouldn't have to install anything unless you're using the system python on linux or mac i don't think that comes with a system python but if you install it if you install python separately you should have tkenter anyway normally without partial you would create an event handler with a lambda or you would just call the command so in this case [Music] if the command didn't take an argument you could just say command equals button event but my button event is special because it wants a label to be passed to it so to make that happen i use a lambda function and basically create an anonymous function that includes the label that is on the button and pass it along um let's see i just want to show you what this looks like before we continue okay so we have some partial callbacks but this one isn't a partial callback yet whenever you press press the button it prints out some text let's see how we can change this to actually use a partial function so now we import partial and instead if we change the lambda to using partial and i think a better example of this would be to actually have multiple buttons using the partial here and i'm actually going to show you an example of that using another gui toolkit but to me i find this code a little bit easier to understand than the lambda code that's probably just the way my brain is wired but to me that just makes more sense and the code operates the exact same way as the lambda did which is actually pretty easy to demonstrate you just open it up and you can keep hitting the button over and over again all right i believe i have a slide on here funk tool dot partial can also be used with wx python now i think you could probably use it with pi cute or pi simple gui or any of those other ones too if you to do something similar um i just have a kind of a love for debex python because i've used it practically since the beginning of learning python so i'm just going to talk about a little bit diabetes python is cool because it lets you when you run it it uses native widgets and what that means is that a daybreak's python application will look like it belongs on mac or linux or windows because it's actually using the widgets that you would normally use if you're using a primary coding language for that platform tkinter draws all of their widgets themselves so it will look the same on all three platforms which may or may not be what you want however dybbex python has a lot more boilerplate so we have this stuff here at the beginning where you basically create your your frame and add a title it's usually best practice to have a wx panel which holds all the widgets that you have on your screen and to make this more interesting to me i went ahead and added three buttons this time so we're gonna loop over some labels for each label we'll create a button add it to our panel which is this widget up here and we'll use our partial function to call our event handler on button and pass along the label now you might be wondering what about event you can see here that i'm not passing the event along when you do button.bind it passes the event implicitly which takes some getting used to because you know python is all about being explicit not implicit but because we're using a c plus plus gui underneath the covers of wx python i think that's why event is kind of implicit here anyway what i like about this particular bit of code and you can clearly see that we're passing the label along and the partial function changes for each button that gets put in there so this makes what's going on a little bit more obvious at least in my mind so you can see when i create this particular function the buttons don't blend in with the background like they did with tcanter because they're actually using proper mac buttons and when you push the buttons it knows that you're pushing the right one because of the partial function being able to pass along the correct label to the event handler most of the time you don't have to pass extra data to an event handler but there are times where it's really helpful especially when you're debugging or if some if you have a really complicated ui all right let's continue on our punk tools adventure um funktools.reduce i found a great article on reduce on real python's website but the documentation is really good too um but you might not realize if you've only been using python 3 is that the reduce function used to be a built-in in python back in python 2 days so you didn't have to import it but when python 3 came out i think there was some disagreement about how often reduce was being used and so it got either removed or just moved into functuals.reduce i can't remember now if i think it was removed for like a version of python and then it got put back in and funktools.reduce i'm sure someone will comment and tell me tell me the history if they if there's someone watching this anyway what it does is it will take it'll apply a function of two arguments cumulatively to the items of an iterable from left to right so as to reduce the iterable to a single value basically it's kind of a way to cumulatively go over an iterable one example that is on the python docs is to call reduce with a lambda of x y and then do x plus y and then do that for each of these items in this list which are iterable what that does is what this does is equivalent to doing one plus two which is three plus three is six plus four is ten plus five is fifteen i'm going to show you some other ways to do that without using a lambda anyway this comes from the that real python example i think it's a little bit clearer a description of how this all works apply a function or callable to the first two items in an interval and generate a partial result i think it's funny that they use the word partial here since functuals has a partial function anyway use that partial result together with the third item or the next item in the iterable and generate another partial result repeat the process until over the entire interval until it's exhausted and then return the single cumulative value all right let's take a look at an example of reduce just kind of nail this down we're going to keep using our add function and this time we're going to pass it to reduce and we'll go ahead and do something similar to that lambda but now we're just going to call add instead of the lambda because before in that that python docs example it was using a lambda function here that i thought was kind of confusing i think this is a little bit clearer too to run okay let's go ahead and run that and i went ahead and printed out what's going on so we can kind of see how reduce works so the first time it runs it calls it with one and two it gets three then it does three and three so you can see it's going left to right and it gets six six and four is ten 10 and 5 is 15 and then it prints out the result at the very end now i'm sure we have some uh functional programmers in the audience who are probably thinking there's extra code here we can make this even smaller and you're right we could so let's look at an example of making it even smaller you could import the ad add function from the operator module and now we've got this done down to three lines of code func tools.reduce add and then the iterable and the results will be exactly the same as the previous one except i don't have all those print statements telling us what it's doing we just have the result of 15. so you know it's fun you can play around with it um and use it i don't think i've actually used reduce in any of my code but it's a i can see why it would be handy in certain situations all right let's continue to function overloading you may not know this but python actually has the capability to overload a function and the way you do that is with the funct tools module what is function overloading anyway it is a generic function um yeah i don't really like the way i wrote this but i'll try to i'll try to make it clearer without reading it entirely okay so function overloading basically you have a generic function that is composed of multiple functions implementing the same operation for different types it's really kind of weird to think about unless you have a function that is kind of like the fallback function or almost a type of its own that you will fall back to if you don't register the other types to it which implementation should be used during a call as determined by the dispatch algorithm now in python dispatching is based on the type of the first argument of a function this is different than c plus plus and i'm sure java does it differently in other languages do differently but i know in c plus plus their function dispatching algorithm can look at multiple arguments in the function so it doesn't just look at the first argument it can look at all of the arguments and so you can have pretty complex function overloading in c plus that python just doesn't support out of the box all right let's take a look at using functools.singledispatch let's see here [Music] how to grab the right example i'll scroll up here to the top so you import it and you'll notice that this one is back to being a decorator whereas reduce and partial were both functions that took other functions now we're back to decorating functions this one's kind of interesting so let's talk just a little bit about what a decorator is because i think i'll make it a little bit more clear what's going on so our decorator takes in another function and modifies it slightly well it doesn't modify the function itself but it can add functionality so you might add some logging to it you might add some authentication to it in this case what we're going to do is we're going to make this add function be overloadable so to speak so it takes two arguments a and b and it immediately raises a not implemented error so this function isn't very useful by itself however when you want to overload it you create another function named underscore with the same arguments and you register it with the name of the generic function so you'll see here instead of at single dispatch you have at add dot register and then whatever type you want to register so in this case we're going to register int and we're going to print out inside this this function we're going to print out the type to verify that we have it working right and then we'll just add it together and print that out down here we're going to go ahead and register the string type 2 and you can see this function is also named underscore normally in python code you can't name multiple functions the same or you'll end up with some kind of syntax error or runtime error even you just have all kinds of weird weird problems because we are registering them using this special syntax python is okay with it i went ahead and created three different functions i went ahead and created a list one as well so it'll take in one list and another list and then add them together basically there are other ways to do this of course i just decided to do it this way and i think we'll just play around with this a little bit and see how it works so let's try running my single dispatch code and you can see that by passing in a list of one two three and a second list of five six seven it calls the correct the correct method because it says classlist here and it's going to use some some chicanery to add them together now let's see what happens if we try to do tuples let's try passing into tuples oh we got that not implemented error unsupported type and where is that coming from that comes from up here in our generic function so because we didn't register tuple in here anywhere we're going to get an error now we could grab this code and just create a function we can call it tuple or register tuple and well let's see if it works you may end up with another error because can you add two tuples together i guess we'll find out let's run this aha so we ran our tuple code now we don't get the not implemented error and we get a tuple with the contents of one and two now just to be clear two balls are immutable so what's happening here is we're creating a third tuple that has the contents of the two tuples combined anyway i think i think this float one will also fail because we don't have floats not figured out yet either yeah we also get a not implemented error because float is not supported we don't have float registered here i've seen i think one instance in my career where i think single dispatch would have helped clean up some some crazy code i was working with and hopefully you're starting to see how you might use it in your own code just like simplify some complex logic i've had to do it with basically what amounted to complex configurations one configuration type might be a type of machinery so i used to work with precision agricultural products and we'd have to load configs for like a planter and a combine and a sprayer and each of those types were different and could be built differently and one of my ideas for cleaning up that code and making it a lot easier to follow was to use single dispatch to dispatch to the functions appropriately to build the configurations i never did get that quite working the way i wanted it to but it would have worked really well if i had it if i had been able to tweak it and had the time to finish messing with it all right i do want to mention that just because python doesn't come with multiple dispatch out of the box it doesn't mean you can't do it there are actually at least two packages that claim to support multiple dispatch in python i keep seeing plot mentioned on twitter i've had several people contact me and point out that plum exists strangely their examples don't actually show multiple dispatch at least i haven't found one yet they all mention one uh all of the examples show like one argument being passed to it but i mean it the whole title is multiple dispatch in python so if you played with plum and seen it work that's awesome i think this looks like a really cool project and i'd like to play around with it some more interestingly this one mentions multiple dispatch and compares it with multiple dispatch which is the other package you can use to support multiple dispatch or multiple overloading with python i'm not sure how this one differs except that it's using a decorator a little bit differently here it's decorator is where you pass in um the types for the ver for the arguments that are getting passed in so you know add takes intent here and this particular ad takes an object object so you can differentiate between them that way this one looks more promising to me than plum does just because the examples actually show multiple dispatch in action but you know i haven't tried either one of them so if you try them out let me know how it goes all right so funktools.wraps i think this might be the last function i want to talk about in funk tools i have a i have a really short tutorial on how to use this appropriately in python on my blog feel free to check that out if you have a moment otherwise oops went too far otherwise let's take a look at an example all right so here we go talk about decorators again here's an example without using the wraps uh method or decorator here we're creating a logging decorator and if you've never seen a decorator before i guess i'll have to break it down for you so to create a decorator the the normal way to do it is to have a nest function inside of it the elder function takes a function as its argument the inner function takes the args and keyword arguments that go to the function that is being wrapped um in this case i'm going to log the args and keyword arguments out to standard out and i'm also going to print out the result of calling the function and then typically when you're done calling the function you return it and then you return the actual wrapper function in your decorator then to apply your decorator you just do at whatever the decorator name is in this case we'll call it a logging decorator and i'll keep using this add function that we've been doing then down here to test it out i do something kind of odd here we're going to try to print out the add function's name using the dunder name method or under name attribute we're also going to print out its stock string using dunder dock dunder being double underscore doc um for those of you who've done this before you're probably going to know what's going to happen but i won't spoil a surprise for those of you who don't so let's go through this you can see with the rx4 and five got passed through i didn't pass any keyword arguments the result is nine name a function is wrapper wait a minute the name of the function should be add not wrapper what is happening is that our decorator is getting replaced with wrapper which you can see right here in the code we're returning wrapper we're not returning the function back so wrapper replaces add entirely as far as python is concerned and so you end up with the name of the function being wrapper and the docs string being wrong as well this can lead to some really frustrating head banging debugging sessions you'd like where is my where's my code wrong is it in this is it in my add function where is it and depending on how you're logging your code it can be really squirrely trying to figure that out i've also heard if you don't fix this particular problem pi test will get angry too and you'll end up with some weird issues with pi test maybe they fixed that since the last time i've i've heard about that anyway it's easy to fix you can use wraps to come to the rescue so from funk tools import wraps add at wraps inside of your decorator and pass in the function that you're decorating to add wraps so now we have our own custom decorator with a decorator inside of it on site inside on the nested function wrapper all the rest of the code is the same so i shouldn't have to explain that again let's go ahead and run this so now we run it the name of the function is now add like it should be and the docs string is now correct a function that adds two values that's all there is to it import wraps slap it in your decorator make sure you put it in the right place because if you put it up here it's not going to work right it has to be nested along with the wrapper function and that'll fix the problem as long as you remember to do that you should have a much better time debugging your code all right so today i've covered punctuals pretty much it's in its entirety we've talked about caching we talked about total ordering um partial which basically creates partial functions that you can use to replace a lambda function if you want to reduce has been hidden in funct tools whereas before it was available everywhere and it's a really handy tool if you need to need that kind of functionality single dispatch is for function overloading and you learned all about that and you also learned about plumb and multiple dispatch packages so if single dispatch doesn't do everything that you need you can rely on those external packages and lastly we learned about wraps which is of course for fiction fixing up your decorators i believe that's all for my presentation so now i can take any questions you might have hey thank you so much mike i was i was just monitoring um chat and we have a few questions um the first is um what are the effects of using these kinds of functions uh with pi pi so for example when you're using total ordering or partial like you did you ever notice any change in performance was it positive negative um i haven't done a lot with pi by but i believe i believe it should work just fine in pipeline i don't think it's going to to i mean pipe is already faster than regular python so i don't think it's going to be you know make pie pie slower than regular python would be all right makes sense yeah i mean uh my my initial um idea for that is that pie pie also doesn't support um uh tail end uh recursion if i if i understand correctly oh yeah so i remember so there there shouldn't really be much of a change in terms of performance i mean it should be faster but you're already using different fund tools methods and functions to to optimize your performance so it shouldn't make that much of a difference yeah okay so this one this one is a really good one which is can i use cash or li lru cash on async functions uh i would ask you a further question would that be a good idea i would ask that too um you know i've never used it on an async function so i don't know the answer to that one but but why wouldn't it be a good idea though like what could go wrong hmm i'm assuming you have an idea because i actually don't at the moment i mean if you're trying to optimize for performance and if it's uh you know if it if it does some compute then then yeah i don't see much of a change but for example if you know the way that async works is that it executes and then it goes on to something else so there's a lot of time sharing and i'm just worried uh what that would mean um when you're trying to uh you know get get the response from a function that that is kind of order dependent um yeah yeah so that would be uh that would be a quagmire for sure yeah that makes me really curious i might have to go go do some research on that yeah maybe you can blow up a few things and we can have another webinar um so uh this is this is a person who asked about the lru cache have you ever had an issue with the max size of the lru cache not being respected so like you would set a max size to like 100 or 200 and then what would happen is that it would go over the max size you would get like um i don't know a memory leak of some sort and then your computer or so your application would crash in would need to be restarted have you ever had um an issue like that i personally haven't i mean i could see i guess i could see that happening if you're like running on a raspberry pi or something and you try to you know download too much data or try to use the function too much and you just end up hitting that and then you just have to tweak your cash until you find the right that's the sweet spot for your for that type of machine yeah so just the clarification on the initial question that we had with pie pie uh what he wanted to know what what carlos wanted to know is um pie pie uh without any caching just your regular stuff versus python using cash and punk tools and and other things and i don't really know if that is a fair question because if something is algorithmically superior it's supposed to be faster i don't know what would you say i would agree i haven't i personally haven't played with pie pie enough i've done i've done some little little tests with it but i never was able to convince my bosses to give it a serious try so yeah i mean it would be interesting to to pi pi more in production applications i agree um um so this is this is a question for me this is something that i was curious about because like um if you if you go back to your code and if you take a look at the way you do single dispatch and functools you have like a function you add a decorator on top of it and then you add a couple of functions that are basically underscores is there a way to kind of put this in a class and have that be called because it just feels neater to me instead of having a file and on the top level you have like functions and underscores and decorators all throughout you know i've never done a huge deep dive into that but can you use that in a class a good a good question you would think you could but i'm assuming you do it on the methods yeah it's it's more of a aesthetic thing i guess uh more than anything else i mean single dispatch on us in in a normal python file and everything top level works but it just looks kind of weird yeah it looks like and this is what i would expect you could definitely do that in a class instead okay yeah so you'd you'd basically treat them as oh you'd have like a class create an instance and you'd be calling it yeah i believe that would work you probably might have to do just a smidge of meta programming but i think looks like that i think it looks like there's a way to make it work yeah i'm just thinking whether you classify them as class methods or static methods because in this example it seems like they're instance methods yeah right now they're instance methods you might have to i yeah i haven't actually tried that that's also a really neat idea and uh yeah so christian muller says can you implement the class as a callable to make this work i guess that is what you would have to do um if you wanted the ergonomics i think what me and mike were talking about was more like having static methods on on a class body and reusing those methods yeah oh yeah okay then um i guess that's all the questions that we have uh for today um thank you mike so much for joining us and uh hope to see you again soon and before we wrap up we just have some information um if you'd like to follow us on pycharm you can do that on twitter at pycharm you can also subscribe to our youtube channel you can also follow mike on twitter at driscollis he's also available on github with the same name for scholas and please don't forget to like and subscribe uh the video we really appreciate you all uh showing up here and uh if you want more of these please subscribe so that we know that this is uh something useful so that's it thank you so much for coming and see you again next time and thank you mike once more for joining us thank you bye you
Info
Channel: PyCharm, a JetBrains IDE
Views: 6,156
Rating: undefined out of 5
Keywords: pycharm, webinar
Id: t4zln38ABsE
Channel Id: undefined
Length: 48min 18sec (2898 seconds)
Published: Fri May 27 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.