4 ms·
A proper use for namedtuple: @property def coordinates(): x = self.calculateX() y = self.calculateY() return x, y this could b
by sametmax 9y ago
A proper use for namedtuple:
@property
def coordinates():
x = self.calculateX()
y = self.calculateY()
return x, y
this could become:
Point = namedtuple('Point', ('x', 'y'))
@property
def coordinates():
x = self.calculateX()
y = self.calculateY()
return Point(x, y)
It stays compatible with the previous implementation. as you can still do:
x, y = stuff.coordinates
But now can do:
point = stuff.coordinates
point.x
The same example apply for a row a from timeseries in a database or a line of stats in a csv.
But now imagine you have a response from a ldap server returning a list of authorized person. You could manipulate those persons in a dictionary. Some people may want to have a nicer way to access them, with the look up syntax. You can be tempted to use a namedtuple here, but that make no sense, as a person is not iterable. The alternative is to use empty class, but it's very verbose.
But now you can use types.SimpleNameSpace:
>>> class Person(types.SimpleNamespace): pass
>>> p = Person(name='foo', age=12) # no __init__ to write
>>> p # free repr
Person(age=12, name='foo')
>>> p.age # nice access syntax
12
The good thing is that if you ever need to extend Person to later have a more complex behavior, you can just do so as it's a regular class.
The bad things are:
- you may need something immutable
- you may want some checks done to restrict the attributes used
Which is why currently people abuse namedtuple. We don't have a good story for those. Hence the debate on the mailing list.
Nevertheless, it's good to remember that the Python community has a philosophy of "we are all consenting adults here" and a good track record for following it. immutability and attributes restrictions are not definitive show stoppers in Python, and SimpleNameSpace is a decent solution while waiting a purer to come up.
- eesmith 9y agoYour example with Point() is exactly what I said was a good use case, for apparently the same reasons why I said it was a good use case. I said "'namedtuple' has one good use - migration from a tuple object to a real object while allowing backwards compatability to the tuple API. ... It's also fine if it will only be used by code where you have full control over its use and can either prevent inappropriate API use ... Otherwise, don't use it." You replied "Only if one is misusing namedtuple". I interpreted this as an objection to my use guidelines. From what I can tell, you are in complete agreement with me.