4 ms·
I 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 o
by musha68k 5y ago
I 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 agoCan you point to any public codebases which illustrate this approach in Python? I would love to see some of these principles in action.
- rmbyrro 5y ago> Don't use classes for information. Use regular data structures (dict, list, tuple, set) and use functions to manipulate them. One problem is many of these datastructures are easy to mutate. When I need to ensure immutability to a dictionary, for instance - quite often - I can't avoid wrapping it in a class and setting up an interface to lock down mutation. If Python had a way to declare immutable datastructure, similarly to Clojure, it would make life a lot easier...
- galoisscobi 5y agoFrozen dataclass instances (https://docs.python.org/3/library/dataclasses.html#frozen-instances https://docs.python.org/3/library/dataclasses.html#frozen-in...) might be of help.
- rmbyrro 5y agoWasn't aware of this feature in dataclasses, that can be helpful in a few cases, thanks for pointing out
- ciupicri 5y ago> class types.MappingProxyType(mapping) > Read-only proxy of a mapping. It provides a dynamic view on the mapping’s entries, which means that when the mapping changes, the view reflects these changes. https://docs.python.org/3/library/types.html#types.MappingProxyType https://docs.python.org/3/library/types.html#types.MappingPr...
- rmbyrro 5y agoThis can be helpful in some cases, but it's precisely what I sometimes need to avoid, which is protecting a dictionary and having changes affecting only its own scope. If function A passes a dict to function B, I would like: 1) Function A to keep the dict intact while function B can manipulate its content; 2) Function A can change the dict after passing to B, and B still keep the original copy, unaware of A's later changes. One way of doing this is by deep copying dictionaries around, but it can easily become a big performance issue.
- javcasas 5y agoScrap all the factories. The class name is also a function and a constructor. Just pass it around as parameter, and bypass all the factory stuff. Use named parameters and bypass the builder pattern. Store operations in objects/lists. Bypass the strategy patterns with this knowledge. Did you know myobject.mymethod is a function, and you can do x = myobject.mymethod, and then x()? Store methods in lists, pass them as parameters, partially-apply parameters to them. Generators are more than what the iterator pattern will never be.
- qbasic_forever 5y agoLearn Go and spend some time in its world, then come back to Python IMHO. You'll start to appreciate the subset of Python that's just functions at the module and class level and ignore all the complexities of metaprogramming, class hierarchies, etc. You'll find a lot of folks using Go are coming from Python and burnt out on big, complex codebases there--the simplicity and "less is more" is a breath of fresh air to reapply to Python.