Improving your code readability with namedtuples
python-programming.courses
python-programming.courses
Let me dream :)
Person = Struct.new :name, :age
people = [
Person.new('Alice', 42),
Person.new('Bob', 23),
Person.new('Carol', 30)
]
people.sort_by(&:age).map(&:name)
# => ["Bob", "Carol", "Alice"]https://hg.python.org/cpython/file/tip/Lib/collections/__ini...
I would settle for better namedtuple syntax though.
I tend to reach for namedtuples first now over classes because of this (and the fact that I don't do as much OOP in general).
For example, the following pattern would improve code readability as well (by making values available as attributes) but also allows you to extend it in the future when you need to add additional methods to your object:
class Person(object):
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
Example: p = Person(name="John", age=30, weight=78) and p.age for access. When needed you can add methods to this class while still keeping the code readable. class Person(namedtuple('Person', 'age weight height')):
def is_adult(self):
return self.age >= 18 class Foo(namedtuple("Foo", "a b c")):
__slots__ = ()
def abc(self):
return self.a + self.b + self.cBoth in a "eat your vegetables" sense (it's good in general to have immutable data structures where possible, that's one cause of bugs eliminated), and for practical reasons such as using them as keys of dictionaries, and as elements of sets.
You can also _inherit_ from namedtuples, in case you want to add methods.
The overall codebase used in this example is smelly.
Shortcomings are that it's not in stdlib and does have a few quirks (for example, be sure to convert a Dict to a dict with .to_dict() before json'ing). However, it's a nice and well maintained module.
What keys does the dictionary "person_data" have? Well, originally it only contained username and email address, later we added street address (everywhere where it was used, we think). And then came preferred language, but that was only added in the functions that care about that. And so on, and so forth...
Eventually all functions work with a slightly different version of a person_data dict, you're never quite sure which one a given function expects, and there is no central definition. Death by duck typing.
Dicts are for algorithms, they shouldn't be the go-to tool for structs of data. That's what classes and namedtuples are for.
age, height, weight = person_data
Silly example for such a useful tool.They also let you improve readability (as the article states), while being full compatible with the ordinary tuple api. In other words, I can make a named tuple where I think it will improve my own code, and then pass it into someone else's code that is expecting a tuple and it will work. If you had used a dict or somesuch in this scenario, you would have to do something to marshall the state back into a tuple before you could pass the data into some library that expects tuples, e.g. numpy or something.