4 ms·
I watched an earlier version of Raymond's talk and I skimmed through the other one. One thing that I think they both mention is that to take advantage of some
by ericfrederich 9y ago
I watched an earlier version of Raymond's talk and I skimmed through the other one. One thing that I think they both mention is that to take advantage of some of these improvements you need to set every attribute any instance of your class will ever set on the __init__ method.
This is probably a good practice anyway. I'm curious now how I can test and see if I'm taking advantage of this or not. I wonder if using the attrs module will also make use of this new feature.
- m_mueller 9y agoI'm starting to wonder whether it wouldn't be a better design to forget about classes for most use cases, instead only use namedtuples and have a bunch of functions defined that take one type of namedtuple in their first argument. You can easily bind this by doing my_applied_func = functools.partial(my_func, my_named_tuple). This design IMO has a few advantages compared to classes: * __repr__ comes for free. * converting all members to a list or dict comes for free. * converting a list or dict TO a namedtuple comes for free. * more restrictive in what you can do with data structures inside the namedtuple - may lead to a cleaner design where you think about pulling apart the data into multiple tuples at an earlier point in the prototype phase. * You by design won't make functions into instance methods that depend on multiple data tuples. * Need to extend a function to deal with different types of tuples? You now don't need to refactor an instance method into a first class function, instead just dispatch and be done. * Inheritance can be solved with the above method as well. This may actually be more maintainable than class based inheritance, since you see all the logic for a specific function explicitely (or explicitely dispatched) in one place. The only reason I can think of to still use a class: If you can heavily profit from inheritance or if you need to program against an "interface" like dict- or listlike behavior or comparison operators.
- ericfrederich 9y agoA lot of your points are solved with attrs. I suggest reading up on it if you haven't already. http://www.attrs.org/en/stable/ http://www.attrs.org/en/stable/ I think organizing / refactoring a bunch of named tuples would be a mess. In one code base I maintain I switched a bunch of namedtuples to attrs classes and the code instantly became more readable / maintainable. The downside to the namedtuple is that it's a tuple and can be unpacked as one. for x, y in points: print x, y # vs. for p in points: print p.x, p.y # ... now go and add a z to the point class and see what happens to your code.
- m_mueller 9y agoI don't get your point about unpacking yet to be honest. Both your code examples work fine with namedtuples I think. Adding additional attributes is better in the second example, which is why it is to be preferred, but that works with namedtuples as far as I understand.
- maxerickson 9y agoAdding a member to the tuple requires updating all code that unpacks it. Adding an attribute doesn't impact any code that doesn't use the attribute.
- m_mueller 9y agoYes, that's why you usually don't use unpacking for a namedtuple. This works just fine without me adding additional 3rd party packages: > from collections import namedtuple > Point = namedtuple('Point', ['x', 'y']) > points = [Point(3,4), Point(5,2)] > for p in points: > print(p.x, p.y)