4 ms·
There is also a NamedTuple (notice the different casing) from the typing library, which doesn't seem to be mentioned in the article: https://docs.python.org/3/
by nikeee 5y ago
There is also a NamedTuple (notice the different casing) from the typing library, which doesn't seem to be mentioned in the article:
https://docs.python.org/3/library/typing.html#typing.NamedTuple https://docs.python.org/3/library/typing.html#typing.NamedTu...
class Employee(NamedTuple):
name: str
id: int
This is equivalent to:
Employee = collections.namedtuple('Employee', ['name', 'id'])
- colejohnson66 5y agoI don’t use Python much, but what’s the difference between a NamedTuple and a regular class?
- akoumis 5y agoNamedTuple is purely a data container. It does not have class functions or a constructor you can use for anything other than setting the data members.
- ZuLuuuuuu 5y agoNamedTuple has the features of a tuple, for example it is immutable. A regular class is mutable.
- palotasb 5y agoNamedTuple or namedtuple instances are tuple instances that have the same properties that regular tuples have. They are immutable (you cannot reassign their fields), you can index into them (a[0], a[1] instead of a.x and a.y), you can unpack them with *a. They can have methods like regular classes can, including additional @property methods. A NamedTuple class cannot inherit from another class, not even other named tuples.
- dec0dedab0de 5y agoa named tuple works exactly like a tuple, except you can also use names to get the items in it. so it is immutable and you can get it via slicing. >>> from collections import namedtuple >>> Hat = namedtuple('Hat', ['style', 'size', 'color']) >>> my_hat = Hat('safari', 'XL', 'Orange') >>> my_hat Hat(style='safari', size='XL', color='Orange') >>> my_hat[0] 'safari' >>> my_hat.color 'Orange' >>> my_hat[1:] ('XL', 'Orange') >>> style, size, color = my_hat >>> size 'XL' >>> If thats all your using your classes for, then a named tuple is probably a better solution, or a dataclass. Though I normally just use dicts in that situation. If I see someone create a class without any methods, or atleast planned methods, I don't let it through code review. EDIT: Also, Raymond Hettinger created named tuples. I'm not normally one for call to authority, or hero worship, but I am a huge fan of his. I recommend that anyone interested in Python should watch as many of his talks as they can. EDIT2: As masklinn pointed out, another really good use of named tuples is when you're already returning a tuple, and you realize it would be better if it had names. You could change it to a named tuple without breaking any of the existing code. Unless they're doing something dumb like halfassing type checking at runtime. (this use case is in the article, which i didn't read at first)
- masklinn 5y agoWell in and of itself none, in the sense that anything a namedtuple can do you could do by hand (it really just defines a class). However namedtuple: * extends tuples, so a namedtuple is literally a tuple (which is useful) * sets up a bunch of properties for the "named fields", which are basically just names on the tuple elements * sets up a few other utility methods e.g. nice formatting, `_make`, `_asdict`, `_replace` Now the latter two are nice, and mostly replicated by dataclasses (or attrs). The first one is the raison d'être of namedtuples though: originally their purpose is to "upgrade" tuple return values into richer / clearer types e.g. urlparse originally returned a 6-utple which is not necessarily super wieldy / clear, you can probably infer that the 3rd element is the path but… after upgrading to namedtuple it's just `result.path which is usually much clearer. And because namedtuples are still classes in and of themselves, you can inherit from them to create a class with a `__dict__` with relative ease.
- agumonkey 5y agoI think it was a pre-organized immutable data class in one line.
- Spivak 5y agoI feel like none of the sibling answers actually answer your question which is "absolutely nothing." The function namedtuple is code generator that constructs a class definition and then eval()'s it. The reason you reach for it is because it's tedious to write the same methods over and over to get things like a nice repr, methods covert between dicts, or pickling support. The source from Python 3.6 is much more readable than 3.9 so I recommend reading that if you want to see how it works. https://github.com/python/cpython/blob/3.6/Lib/collections/__init__.py https://github.com/python/cpython/blob/3.6/Lib/collections/_...
- Nagyman 5y agoIt is mentioned if you expand the "In case you've never used them, here's a comparison." element.
- ziml77 5y agoI like that method of defining a named tuple much more. I understand why it's required, but having to duplicate the name of the named tuple always bothered me. The type hints are excellent to have too.
- Spivak 5y agoI don't know what you're talking about, I always confuse my coworkers by doing Pointe = namedtuple('Point'...
- wizzwizz4 5y agoThis breaks pickle, among other things.
- Spivak 5y agoIt really shouldn't. This is actually an example of pickle being broken. The class exists, there is an existing valid reference to it, and Python itself knows about it and the class itself knows its own name and namedtuple generates the right __getnewargs__. Everything is there for this to "just work" but pickle expects that every class object will have a reference to it of the same name which is kinda weird when you think about it. You can see it with this stupid little program. from collections import namedtuple import pickle def get_all_subclasses(cls): all_subclasses = [] for subclass in cls.__subclasses__(): if subclass != type: all_subclasses.append(subclass) all_subclasses.extend(get_all_subclasses(subclass)) return all_subclasses E = namedtuple('EEEEEEEEEEEEEEEEEEE', 'x') e = E(x='hello') for cls in get_all_subclasses(object): print(cls) pickle.dumps(e) You'll that the class it there and called the right thing! But pickle tries to look up a reference to it under __main__.
- wizzwizz4 5y ago> but pickle expects that every class object will have a reference to it of the same name Yeah: its qualname. The qualname, as per PEP 3155, is defined as: > a dotted path leading to the object from the module top-level so of course pickle can't cope with this information being incorrect. (How would you make it work?)
- mikepurvis 5y agoThat's awesome and I was not previously aware of it. Literally a decade ago I was asking on SO about exactly this kind of use-case [1] and at the time the answers were pretty unsatisfying; it's great to hear that the story is better now. [1]: https://stackoverflow.com/questions/4071765/in-python-how-do-i-call-the-super-class-when-its-a-one-off-namedtuple https://stackoverflow.com/questions/4071765/in-python-how-do...