 Hi, everyone. I want to tell you a little story. Of course, not about myself. It will be a story of a Python developer. Not so long ago, there was a Python developer. And throughout his career that lasted already several years, he write a few thousands of lines of code. And he was in love with his favorite framework. And he became so proficient in the tools he used daily that he even became a mentor for his teammates. And he praised all the tools he used because they were able to solve all his problems he dealt with in daily work. And after all, he was quite good. And this really boosted his self-confidence. And this isn't surprising. Of course, knowing a framework was not his only asset. He practiced writing tests rigorously and applied TDD whenever it was applicable. He was doing his best to make sure that the code he written was not only correct and well tested, but also readable and easy to understand by any other teammates. And every night before falling asleep, he was reading a Zen of Python to write a code that would never violate any of its verses. In other words, he was doing his best. And he was expecting the other teammates to do the same thing. And then he was assigned to a new project that changed everything. Well, despite the fact that our hero was proficient with his tools and he know them inside out, they were not well suited for the project he was assigned to. Because how valuable this experience may be when the weight of the project, its very business part, is far outside this framework. And it can no longer be solved by this framework, essentially. So he started to create his own classes, his own modules, and his own abstractions. And he felt that they were clumsy, and they do not be as good as the well-thought components of a framework he used daily. You see, frameworks are sets of powerful building blocks. If you use them for problems that they were created for, you're fine. And you shouldn't bother any other options. But the problem arises when there is an issue that they simply don't fit. And you try to effectively screw driving using a hammer. And for example, what would be the Django good for if you did not need to use its models at all? So what's left? I don't know, the views, the template system, and the routing. And that's all. Any other rich capabilities of Django are not used, so why would you do that? And the problem why our developer was stuck was that he lacked the thinking outside the box beyond his manual. And luckily, he noted this problem eerily enough to come up with an idea of asking someone maybe more experienced, maybe more interested in software engineering. And he had a friend, a Java developer, and he asked her for an advice. What should I do if my tools are not good enough for me for this particular problem? And she said, take a look at design patterns. They are meant to be reusable concepts to produce elegant code and nice solutions and are based on many years of experience, people that are much smarter than we are. So our hero took the design patterns, took the 23 years of book, and tried to implement some of those using examples there. However, the design patterns are not like libraries or tools that he dealt so far, so they are not easy to use solutions that you just import in your code and start using. They are more like re-scipes, like drafts for solutions. If you have this particular problem and they fit, like you have an analogy, then you can use them. But they are just outlines. They are not ready to use. Maybe you are thinking, what are they good for you if they are written in some old books by some C++ guys? Well, there's a funny fact about IT. Namely, our brand has some kind of amnesia, any 20 or 30 years or so. We forgot about old concepts, old ideas, and then we discovered them again and we were like, oh my God, this is so amazing. Cool. For example, let's take an Async.io and its core routines, yeah? Cool idea, the event loop. Except it's nothing new because this is almost 50 years old now and it's been around in the 70s. But we just now got it to the Python. Another thing to consider when you think about patterns is that are they applicable today? And well, the book was written 23 years ago which there were different tools in charge instead of Python. So, Python simplifies a lot of things and this is what the stock will be about, more about the tools and less about the design patterns because you will see that some of them are also present in Python but they are already invisible or you cannot differentiate one from another because they are so, so simple. But the main benefit from design patterns or at least learning the application in Python in some limited way would be for you to extend your toolbox as a programmer and as a result become not only a better Python programmer but a better programmer in general. Okay, so let's start with the first pattern. There is sometimes considered an anti-pattern, a singleton. This is a situation when you have a class and in any moment of lifetime of a program you need only one instance of a given class. Only one object has sense. There may be several reasons for that. Maybe all the objects will be the same. So why should I bother and why create new things every time? And maybe there is a business motivation behind this that there would be no more than one object or maybe creating an object costs a lot, takes a lot of time and you just want to avoid it to get some speed up. And for such cases we can use a singleton pattern and beside uniqueness there is also one requirement namely you need to have a clear way to get an instance and know that this is a singleton. So after googling a little, you may find the following solution and this uses a magic Dunder new method that is using during creation. So this solution comes down to using a class level attribute that will store your only instance and eventually return this whenever it's necessary. Using this is quite simple, you just create as usual as you would like to create the other object. And of course you can use this implementation in your programs but please don't call yourself Pythonistas anymore because there is one very serious flow I can see this and this is that it's not clear for a client of this class if he creates a singleton if it's really an unique object because we use an usual syntax for creating a new object. So you might get surprised if that you really use getting is the same thing over and over again. A slightly better approach is to use a class method. Class method has this advantage, this is more clear and it also does not block you from creating an usual instance. Well you could do the same by clearing that class level instance variable but we don't want to go that far. However, since we have Python and it's 2017 there is a simpler way and actually it's been around in Python for several years I guess or more and this is you can just create an instance object in your module and later in your code just import the object instead of class and this will achieve actually the same thing. So I told you that some patterns are present in Python and this is true about singleton. This is not an obvious fact but there is a creature in Python that you use it countless times and actually meets the requirements for singleton and this creature is called a module. So let's consider this. After importing a module at least once there is exactly one instance of it in this module's dict object. You can very easy and very clearly get an instance of a module using import statement and if you need you can recreate the instance using reload. So this actually adds something to this pattern. So the conclusion about singleton is that using the most simplest solutions would be our way out instead of creating some clumsy classes and if I am speaking about modules there is another pattern that very gets simplified thanks to them and this is facade. Let's say we have a project that is consisting of many distinct components and we can quite easily assign them to some groups responsible for certain functionalities. For example, we have a group with users that is responsible for getting user authentication and so on. We have a group responsible for block posts, creation, retrieving and other stuff and we have some things related to getting advertisements based on the contents. A net of connection between these classes might look like this and I don't have to tell you that this is a terrible idea because you get a tight coupling between these classes and anytime you want to change something in a class that has many connections with others then there is a probability that you will break things. Also it's very complicated to get desired functionality because you may not know what's behind this subsystem. This is what facades, this is issue what facades tries to address. You introduce in original pattern an extra class that will be your interface to the entire sub module. You are no longer allowed to use these classes directly under no circumstances. All requests that go to this subsystem must go through the facade. And of course you can go on with default implementation like using class methods all over and creating another class but perhaps this is an over-engineering, over-engineered solution in Python if all you need is just a top-level package that will get a bunch of functions inside. Just look how clear it looks compared to the idea of modules. The only thing you use outside this package is imports from this init file. Everything that's in these sub-packages is hidden. You may not use it outside. And this is how you hide the complexity of probably very complicated advertisement subsystem. So this pattern is, it doesn't sound like very original or something but it helps you organize your code and there is very little need for class in Python if you can do this the same in plain module. Another pattern is command. A command is an object-oriented callback. The original implementation assumed that it will be helpful, for example, doing graphical user interfaces because you see when you want, for example, have a reaction on clicking an item in the menu, you don't want to pass too many information to the graphical interface with the same reasons as the facades so you don't want to have too many connections in your system. And the command was meant to pass and configure during runtime your things. Its interface assumed that you have only one method which is execute. And the thing that uses command would just run execute when it needs to. Of course in Python it's over engineered because we can use just a plain function to achieve the same thing. And since functions are first class citizens in Python which means that we can create Python function during runtime, we can pass it to another function and we can return it, then there is no need to create a class. But I remind you, this is quite different times where the basic building block was class so you have classes everywhere. And if everything that your command is doing is just calling another functions of another object with some parameters, then maybe you can use the standard libraries goodies which is FunctalSparsal. And this one allows you to just prepare a collable object that will be accessible later to use. But in conclusion, we do rarely stuff like this in Python which making graphical user interfaces. So this is pattern of very little usage in Python right now. And another pattern is a visitor. And this is actually adopted in Python and it's used but for certain amount of problems. Let's say you have a complicated nested structure that we need to traverse and for each such node we would like to execute our own logic. And this is an example of abstract syntax trees. And this is your code represented as such structure. And this is really use of pylint and other linters which gets your code, turn them into such structure and then per each node it does distinct logic. For example, a root element is always a module and this is represent the whole code. The first thing you have, this is import statement and this is represented as distinct node, yeah? And pylint has different checkers, different strategies, different guidelines for any of these elements. So it is much more clear to just separate this. And this is what visitor is about. It's about getting know what is this node and separating this parsing from others. If we had a static typing just like in Java then we could just implement it like this. We would have a method visit and the arguments would point us what type is this implementation about? Yeah, we get a clear distinction about what to do next. Of course, we don't have such things in Python and the first naive implementation will amount to using big if-else statements which I don't have to add to you that this is ugly and this is gross quickie and it's slow. Luckily, we can use the dynamic nature of Python and create functions that we will call them later as usual methods. After we assemble a methods name, we can just get it from our object and call it just a usual function and this will work fine too. But having Python at least three, having at least Python three dot four, we have this single dispatch functionality which this is the closest what we can get comparing to Java. So it's directing implementations per argument type. Its usage is quite complicated. I will get it step by step. So first of all, we implement the single dispatch and we get a default implementation. Of course, the default if we did not have a specialized version for this time, we will be wanting to rise exception that this no handler is for this thing. Then we would start implementing our all specialized implementations using, take a look at this decorator because we don't use single dispatch, we use the visit decorator dot register and this decorator gets the only argument which is a type, a type of a first argument to this function and whenever you call a visit with a type like in this place, then this registered function will be called. Unluckily, this has a major disadvantage and namely it cannot be used in classes because there's always a first argument is a class. It would have to be re-implemented by hand in such case. Okay and the last design pattern is decorator and decorator pattern is not what you might think of when you hear a word decorator. It's not the decorator function in Python. It will become more clear when I was showing an examples and now some requirements. It can extend the behavior of a given object during runtime and it can be used multiple times with different decorator patterns and no order is not important. They should work the same way or at least have a meaning desired. So a decorator, when you decorate an object you have to get the same thing back which means as a user of class you shouldn't be aware that this uses a decorator. So if there is any attribute on the object then it should be also present on a decorator. And for example, if we have such class then it has two methods, get text and get number and we would like to decorate one of them by adding some bold HTML markup. Then we have also to reimplement the other function which is also, which is of course redundant and this is just writing a code for art not for making functionalities. But what happens actually if we request an attribute on a class and we use the dot and the methods on the classes and its fields are just attributes and this is a logic we can plug in. So first at all, Python calls a special DunderGetAttribute method and this looks for properties in the object itself. If it wasn't found then DunderGetAtteter I know wonderful naming is called and by default it just raises an exception that this property was not found. And looking for properties is by dictionaries that are per class and per object level. Okay, if the same property is present on class and on object then an object has priority. So to get the creator simplified we can just implement the method we need and for any other thing we just return the stuff from the original object and this frees you from need to implement all this unnecessary stuff. Okay, to get full compatibility you would also have to implement the other methods but that's a different story I guess. So to sum up, a Python is a very flexible tool much different from what we have almost 25 years ago and many of these things you might think are either redundant or extra art just for it but in Python there are multiple places when we can plug in our own logic and customize on nearly every aspect of creation objects to runtime. However, the very important question arises is magic that showed you in some limited way is worth the effort? Should we use really the magic? Well, it depends. The readability wins. There are cases when using this stuff will spare you some effort and any other things that we just create, I know I see a fancy Python feature let's use it, it's a probably wrong idea. And there are three things for me that I want you to take from this presentation to become a better programmer in general. So first of all, get to know with your tools and know them well and this is like vocabulary, like having a name for everything you see. The second way is to get inspiration from other languages and communities because there is not much interest in Python community in general in software engineering. There is not much talks on this top subject, on conferences, there is not much books. And the last thing I haven't spoken earlier is to know a business domain of your project because if you know your tools, you have a vocabulary. If you get inspiration from the languages, you know the software engineering stuff, you have a grammar, but a real value, a real meaning, what you do is in this point. So even if you write a beautiful code and know all the tricks and you still won't be able to solve the problems of your business, of a company you work for, then this is all for nothing. And just to sum up, my name is Sebastian Buczynski. I work for S-Takes Next, the biggest software Python house in Europe. I blog under breadcrumbscollector.tech. And that's all folks. Okay, we have time for about two to three quick questions. So who has a quick question? Anyone? No, everyone has hungry views. There's one. So it's less of a question, but more asking for a comment of you because in my opinion, actually, I come from the Java development community and design patterns are really important. And I also realized they're really important in Python. For example, the facade pattern you mentioned. Sorry, I will keep it short. But my question for your comment is you said that design patterns are not really important in Python, but of the 23 patterns in the Gang of Four book, ah, sorry. Like are they actually really not important or are they important to implement sometimes or just forget about them? So what's your opinion on the design patterns and the importance in Python? Okay, so I mean, your title was design patterns are not important in Python. But honestly, is it important to learn these and then implement them? Or, ah, I'm sorry, I can't really make my question. Okay, so your question was about, is it worth to learn the, okay. So essentially, I think that this is a tricky part for less experienced people, because they learn unnecessary stuff. There is a gap in our community and this is an established set of well-thought best practices. I think this should be prepared by someone, maybe, and this should be well propagated throughout the community. So they do not have to learn from other, from 23 years old books, yeah, because they are not relevant today. So we need just a new set and counter part for Python. Okay, anyone has a question? One more question? Nope. Well, then it's time for lunch, I would say. Give him a hand.