10 ms·
Python Design Patterns (2018)
- gukoff 5y agoI just finished the first chapter, and so far I think it's really worth reading. After years of Python development, I encountered all the same problems and reached all the same conclusions. I wish I read this at the beginning of my career.
- rmbyrro 5y agoSome of these patterns have proved to be really powerful in real-world projects. One challenge is having them fresh on my mind and being able to spot when it makes sense to apply them. Have been thinking about using flashcards and spaced repetition to achieve better retention and ability to apply in practice. Anyone has experience with this?
- nerdponx 5y agoMy experience is that worked, traditional textbook-style exercises are the best way to learn and internalize this kind of knowledge. A combination of shorter exercises with longer open-ended tasks is good. Basically more or less what you'd get on a homework problem set in a university course. Maybe the fact that this kind of work ends up being "spaced repetition" in some sense is part of why it's helpful.
- kaycebasques 5y agoMaybe work from the other direction? Work through each pattern and think about where they might work in your existing codebases and then try implementing them just for the sake of hands-on experience.
- simulo 5y agoI made the experience that they are hard to learn and understand out of context, so practicing on flashcards does not make much sense for me. What I did is programming some mini projects in which one or two patterns are used: Pub-sub is nice in anything UI related, commands+state is great for a simple undo/redo-manager etc.
- rmbyrro 5y agoAgreed. I'd use flashcards just to retain a fresh memory of what I've already learned with proper context and practice.
- brumar 5y agoAs others wrote, in depth practice is a sensible choice. Once it's done, I believe spaced repetition is a nice insurance against memory fading and can be as simple as a few big cards listing the concepts learned even if that's really not what spaced repetition proponent would suggest.
- blt 5y agoUse good libraries and pay attention to what makes them appealing. Large programs should usually be structured as a collection of libraries. When you are designing an API for your own libraries, think back to how other libraries solved similar problems at the API level. Many (most?) worthwhile design patterns can then be derived from scratch as a way to achieve a particular API structure.
- travisjungroth 5y agoInsanely powerful and underutilized technique: write a list of techniques you can apply (in this case, patterns). Just write the names, you want this to be dense. When you have a choice to make, look at the list. It doesn’t take long to scan 12 names.
- rmbyrro 5y agoThat makes sense. Just thought about having the list as a colletion of flashcards and using a software like Anki to automate the revisions. I know and have used these patterns. Some I use frequently, like Observer. The less frequent ones just fade in memory, and I get myself constantly in need to read about many again to refresh and identify which to use in a particular case. And I suspect I'm missing many potential uses, due to not having them very fresh in mind all the time. That's where I presume SRS can help...
- travisjungroth 5y agoI’m very familiar with SRS and I think you don’t need it here. I get what you’re going for. You learn the patterns, but then you don’t recognize the opportunity to use them. You think you have to keep the pattern in your recent memory so you’ll recognize the opportunity to use it. Here’s the trick: you don’t have to recognize the opportunity to use a pattern. You just have to recognize the opportunity to use a pattern. Instead of thinking “ah yes, Builder pattern would go here” you can just think “maybe there’s a pattern that would be useful here. I’ll scan my list of patterns taped to my monitor. Builder would maybe work? I’ll double check what that means”. This is 1. Way easier 2. Consistent across many patterns. Instead of learning to recognize pattern A, B, C and so on, you just get a vague feeling of “pattern”. This (obviously) doesn’t just apply to patterns. Super useful for web frameworks. List the 10 places you could put behavior (model, field, view, etc) and choose consciously. Same for data structures in algorithms and even all sorts of non-programming stuff.
- rr808 5y agoThis is great. I always thought that GoF patterns is largely obsolete in 2022, it would be nice if the author agreed and has a list of GoF patterns that really dont make sense any more. Builder was one I thought should be included but OP seems to think its relevant (though different).
- jerf 5y agoIn terms of obsolete GoF patterns, Flyweight is my nomination. It's not that it's useless, is just that in an era of 64 MB of RAM, it makes sense that people might need to know about it, but in an era of 64 GB of RAM the need is diminished to the point that only the people who have those problems need to worry about it. And if you do have those problems, it isn't even necessarily what you would reach for first. Though it's at least on the list.
- hermitdev 5y agoI think I've used flyweight in exactly one production system, and it was a trading system. Lots of transactions (easily tens or hundred of millions in a given day in a single process), lots of duplicated instrument data. Perfect use case for flyweight. But, yeah. It's a fairly rare use case. Good to know about, but not necessarily one you need to keep fresh in mind, ready for use.
- hcrisp 5y agoLuciano Ramalho in his book "Fluent Python" mentioned that some (most?) of the GoF patterns are unneeded in a dynamic language like Python. I see [0] he is favorable to this site's author, so it is probably worth a look. [0] https://twitter.com/ramalhoorg/status/960746929025142784?s=20&t=5bJW1H_sB25B7KZvwNEX0g https://twitter.com/ramalhoorg/status/960746929025142784?s=2...
- stingraycharles 5y agoInteresting, thanks for sharing. Is the opposite also true, that when a language is statically typed, design patterns are likely to be needed?
- simulo 5y agoNice! I just looked at it yesterday when I was collecting resources on architecture of WebApps in python. I found that Refactoring guru also has python examples for them pattern section.
- rochak 5y agoWell, this post turned out to be a gem. Loved it.
- brumar 5y agoThis is my favorite ressource on the subject. I recommend it as often as possible.
- chapium 5y agoI feel a bit contrarian about design pattern lists. These always seem to contain a list of solutions and after some fancy gymnastics, a list of potential problems they might solve. I feel it might be more useful to create a list of common software problems and follow them with a pattern that helps solve the problem. I think this would help address the issue of these pattern guides being applied overzealously.
- xtiansimon 5y agoCookbook?
- syntaxfree 5y agoPattern clusters would be better. Like “… so you want to design a programming language, this is the Visitor pattern, the Dispatch…”
- amardeep 5y agoReading top comments might make someone feel that this article is not worth reading, but I encourage people to actually read it. Personally I find it really interesting. For eg. reading about prebound methods here: https://python-patterns.guide/python/prebound-methods/ https://python-patterns.guide/python/prebound-methods/. Seasoned python programmers probably wouldn't find anything interesting there, but for me, it was quite useful including instances of where it is being done in python standard library and discussion around when and when shouldn't it be used.
- e19293001 5y agoI agree. The information is interesting to read and it is well written.
- Spivak 5y agoBound methods in Python are one of the keys to enlightenment to understanding its object system -- that self isn't magic and you could implement it yourself (for example having instance methods take a self, and cls parameter) if you wanted. One fun exercise is implementing an object that can "adopt" loose functions. def some_random_function(self) print(self.internal_state) ... mymagicobject.func = some_random_func mymagicobject.func() # -> prints the internal state of the object
- MaxMoney 5y ago
- ThePhysicist 5y agoIf you're interested in Python anti-patterns instead, we wrote an open-source book on them a while ago: https://docs.quantifiedcode.com/python-anti-patterns/ https://docs.quantifiedcode.com/python-anti-patterns/ Hasn't received any updates in the last years but it still holds up quite well, disregarding the Python 2 specific anti-patterns of course which become less and less relevant, as well as the Django-specific ones, which probably are hopelessly outdated.
- IshKebab 5y agoNot a bad list. Feels like most of them should just be linter rules. I also found a few them don't really apply if you're using static types (which you really really really should), e.g. * Returning more than one variable type from function call: That's fine; the type checker will make sure you don't make a mistake. * Asking for permission instead of forgiveness: Makes sense for the example given (`unlink`) but it is better to e.g. check types explicitly with `isinstance()` than to catch `TypeError`.
- ThePhysicist 5y agoYes absolutely, that book was written before type annotations made it into Python though.
- refactor_master 5y agoAsking for permission instead of forgiveness can easily become an anti-pattern in itself, because it allows lazy code that turns `if known type has expected property` into `try prodding this Any object, and catch where it blows up later`
- xvedejas 5y agoThis seems to be missing my biggest gripe: adding new attributes to classes outside of `__init__()` or `__slots__`. Sadly I have to deal with code that does this with some frequency. Sometimes the attribute is added and accessed outside of instance methods entirely, ad-hoc by some caller. The result is total spaghetti. It becomes impossible to really know what the "interface" of the class is when you have to consider this, plus multiple inheritance, plus metaclasses, and then on top of that someone decided to hijack `__getattr__`. If I have to comb through the entire codebase to understand one class, that's a huge antipattern. To avoid this, a lot of the new Python code I write is full of dataclasses. I do feel like I'm leaving a little bit of power on the table, but at least I can understand the code at a glance.
- ericls 5y agoI don’t like these content about programming. Why listing a bunch possible of answers to some solved problems instead of try to dive deep into the problem themselves. This feels like encouraging people to buy a bunch of cameras instead of teaching people how to take good photos. A good solution may end up looking like some patterns, but sourcing good solutions from a pool of patterns is impossible unless the problem you are trying to solve is the exact same as the one a pattern is solving, in the same environment and context. I do find the content can be very useful for many, but can we not call them patterns?
- codr7 5y agoI agree. Heuristics? They're mostly useful as training wheels, once you've solved a couple of similar problems you can probably do better using local knowledge / pattern matching against actual experience. I remember the Bridge pattern helping me along the way, I was trying to design a GUI with multiple back ends in C++.
- musha68k 5y agoI know python (3) is an object oriented programming language by design but none the less I was wondering if some “functional” pythonista’s had recommendations on some good “less (oop) is more” patterns to share in here?
- ElevenPhonons 5y agohttps://github.com/mpkocher/Functional-Programming-Techniques-In-Python https://github.com/mpkocher/Functional-Programming-Technique... I covered a few core concepts (e.g., functions as first-class citizens, closures, partial application, etc...) and added a few real world examples of using a functional centric design. The text/format has some rough edges, but overall I think the text is useful for internalizing how to leverage a functional-ish approach. Other resources. https://github.com/sfermigier/awesome-functional-python https://github.com/sfermigier/awesome-functional-python
- oroul 5y agoIt's hard to completely get away from objects in Python, but I don't think that needs to be an objective to get away from OOP patterns. My suggestions would be: - Don't use classes for information. Use regular data structures (dict, list, tuple, set) and use functions to manipulate them. If you really want/need something like a struct, use a dataclass. - The itertools module has a bunch of useful constructs for creating and combining iterators. Take advantage of Python's iterators and construct your own when necessary. - List comprehensions and generator expressions are great for clear and concise data transformations - You're going to have to deal with state somewhere in your program. That's fine, some state is necessary to do real work. Don't feel bad about creating classes for things like context managers (e.g. for a database connection) so you can use it in a with statement and it will handle the setup and teardown logic for you. That way your business logic stays concise and Pythonic since those classes can be in separate modules and imported as necessary. I've found this 'functions in the front, classes in the back' approach to writing Python useful as it lets me think about what my program does in a functional manner without denying myself the ergonomics of Python's class-based ecosystem.
- blunte 5y ago
- deleted 5y ago[deleted]
- carapace 5y agoFWIW, if you really want to understand Pattern Language you should go and read the source material: Christopher Alexander's book of the same name and it's companion volumes. The GoF did a fine job, but there's a richer and deeper constellation of ideas and philosophy and design strategies in the original material. - - - - In re: Singleton pattern in Python: one interesting technique is to use a module as a singleton. When client modules "import singlefoo" the first import caches the module object (in the sys.modules dict) and subsequent imports use it: presto! Singleton!
- codr7 5y agoMy first thought was that it's nice to see someone take such a humane and scientific approach to public spaces, and a lot of it makes sense. But to me that's the real essence of the book, not the fact that it contains patterns. It should be required reading for city planners, not software developers.
- sateesh 5y agoYeah, this is usually the best way for creating singleton in Python. But this makes mocking the singleton module in unit tests harder, as this line is run during module import itself. If the singleton is making a network connection (say) and you want to mock it for the unit tests, things get clumsy and harder.
- bmn__ 5y ago> there's a richer and deeper constellation of ideas and philosophy and design strategies in the original material Explanation with a bit more details: https://perl.plover.com/yak/design/ https://perl.plover.com/yak/design/
- sgt 5y agoNot idiomatic Python. Don't model your best practices in Python based on what makes sense in e.g. C++ and Java.
- munro 5y ago100000%, Python is really excelling at functional programming these days. With dataclasses & typing we now effectively have GADTs. Every few months I'm noticing small functional improvements, and I'm loving it! Even though it says `class`, I use it for GADTs, Protocols, and eDSLs--and it feels very idiomatic. These are the 'patterns' you see in SQLAlchemy, jax, pytorch.
- nuclearnice1 5y agoInteresting stuff! What are the sources to learn more?
- nooorofe 5y ago> Python Design Patterns My brain puts it next to: globe of China, Jewish Olympic games (real thing).
- klysm 5y agoIn my experience, developers that reach for design patterns recently read a design patterns book and are desperate to apply them to problems, instead of trying to figure out the best solution to the problem. Design patterns (imo) should be used to get a feel for the design space that you can choose from, but it’s far from a total enumeration.
- mariocesar 5y agoMost of the patterns I haven't seen in practice. Aiohttp, Django, FastAPI, PyTest. They have a blend between monkey patching and metaclasses. It's strange not seeing them more deeply on that list. It kind it touches what you will study in pre academia for Java or C++ workshops courses and not what you will see applied in the industry.
- asicsp 5y agoSimilar resources: * Clean Architectures in Python: https://www.thedigitalcatbooks.com/pycabook-introduction/ https://www.thedigitalcatbooks.com/pycabook-introduction/ * Architecture Patterns with Python: https://www.cosmicpython.com/book/preface.html https://www.cosmicpython.com/book/preface.html * Collection of design patterns and idioms: https://github.com/faif/python-patterns https://github.com/faif/python-patterns)
- RandyRanderson 5y agoThey're coming for python now. Want to reverse a string? You simply need an abstract-factory-decorator-observer. The 'enterprise python' battle begins. Good luck.
- Smaug123 5y agoUnrelated soundbite by Peter Norvig: "Design patterns are bug reports against your programming language.".