Python collections.namedtuple() is confused
documentation says that any Python valid identifier can be field_name, except for those that start with an underscore, which is fine.
rename parameter is true, it replaces the invalid field name with a valid field name, but in the example specified here, it
replaces it with
_1 or _3, how? These begin with an underscore!
The documentation also says:
If verbose is true, the class definition is printed just before being built
What exactly does this mean?
The reason why you cannot use an underscore at the beginning of a name is that these might conflict with the method name provided by the class (for example,
Because just a number is not a valid Python name
, any name that is invalid as an attribute (and therefore not a valid Python identifier or name that begins with an underscore) is replaced with an underscore + position number. This means that these generated names cannot conflict with valid names or with methods provided on the type.
This does not contradict the name you can choose; Given the limitations, it’s actually the perfect fallback. In addition, the names generated in this way are easy to deduce; The properties of these values are directly related to their indexes in the tuple.
As for setting
True, it follows the instructions on the tin box. The source code for the generated
namedtuple class is printed to
>>> from collections import namedtuple >>> namedtuple('foo', 'bar baz', verbose=True) class foo(tuple): 'foo(bar, baz)' __slots__ = () _fields = ('bar', 'baz') def __new__(_cls, bar, baz): 'Create new instance of foo(bar, baz)' return _tuple.__new__(_cls, (bar, baz)) @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new foo object from a sequence or iterable' result = new(cls, iterable) if len(result) != 2: raise TypeError('Expected 2 arguments, got %d' % len(result)) return result def __repr__(self): 'Return a nicely formatted representation string' return 'foo(bar=%r, baz=%r)' % self def _asdict(self): 'Return a new OrderedDict which maps field names to their values' return OrderedDict(zip(self._fields, self)) def _replace(_self, **kwds): 'Return a new foo object replacing specified fields with new values' result = _self._make(map(kwds.pop, ('bar', 'baz'), _self)) if kwds: raise ValueError('Got unexpected field names: %r' % kwds.keys()) return result def __getnewargs__(self): 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) __dict__ = _property(_asdict) def __getstate__(self): 'Exclude the OrderedDict from pickling' pass bar = _property(_itemgetter(0), doc='Alias for field number 0') baz = _property(_itemgetter(1), doc='Alias for field number 1') <class '__main__.foo'>
This allows you to examine the exact content generated for your class.