Never create classes. At least the OOP kind of classes in Python being discussed.
Consider this simplistic class:
class Person(object):
def __init__(self, id, name, city, account_balance):
self.id = id
self.name = name
self.city = city
self.account_balance = account_balance
def adjust_balance(self, offset):
self.account_balance += offset
if __name__ == "__main__":
p = Person(123, "bob", "boston", 100.0)
p.adjust_balance(50.0)
print("done!: {}".format(p.__dict__))
vs this namedtuple version:
from collections import namedtuple
Person = namedtuple("Person", ["id", "name", "city", "account_balance"])
def adjust_balance(person, offset):
return person._replace(account_balance=person.account_balance + offset)
if __name__ == "__main__":
p = Person(123, "bob", "boston", 100.0)
p = adjust_balance(p, 50.0)
print("done!: {}".format(p))
The namedtuple approach is better because:
- namedtuples have more concise syntax and standard usage.
- In terms of understanding existing code, namedtuples are basically effortless to understand. Classes are more complex. And classes can get very complex for humans to read.
- namedtuples are immutable. Managing mutable state adds unnecessary complexity.
- class
inheritance
adds complexity, and hides complexity.
I can't see a single advantage to using OOP classes. Obviously, if you are used to OOP, or you have to interface with code that requires classes like Django.
BTW, most other languages have some record type feature like namedtuples. Scala, for example, has case classes. This logic applies equally there.