diff options
-rw-r--r-- | Doc/library/collections.rst | 65 | ||||
-rw-r--r-- | Lib/collections/__init__.py | 19 |
2 files changed, 42 insertions, 42 deletions
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 2cd8c21..c893e22 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -711,47 +711,48 @@ they add the ability to access fields by name instead of position index. >>> p = Point(x=10, y=11) >>> # Example using the verbose option to print the class definition - >>> Point = namedtuple('Point', 'x y', verbose=True) + >>> Point = namedtuple('Point', ['x', 'y'], verbose=True) class Point(tuple): - 'Point(x, y)' + 'Point(x, y)' <BLANKLINE> - __slots__ = () + __slots__ = () <BLANKLINE> - _fields = ('x', 'y') + _fields = ('x', 'y') <BLANKLINE> - def __new__(_cls, x, y): - 'Create a new instance of Point(x, y)' - return _tuple.__new__(_cls, (x, y)) + def __new__(_cls, x, y): + 'Create a new instance of Point(x, y)' + return _tuple.__new__(_cls, (x, y)) <BLANKLINE> - @classmethod - def _make(cls, iterable, new=tuple.__new__, len=len): - 'Make a new Point 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 + @classmethod + def _make(cls, iterable, new=tuple.__new__, len=len): + 'Make a new Point 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 <BLANKLINE> - def __repr__(self): - 'Return a nicely formatted representation string' - return self.__class__.__name__ + '(x=%r, y=%r)' % self + def __repr__(self): + 'Return a nicely formatted representation string' + return self.__class__.__name__ + '(x=%r, y=%r)' % self <BLANKLINE> - def _asdict(self): - 'Return a new OrderedDict which maps field names to their values' - return OrderedDict(zip(self._fields, self)) + def _asdict(self): + 'Return a new OrderedDict which maps field names to their values' + return OrderedDict(zip(self._fields, self)) <BLANKLINE> - def _replace(_self, **kwds): - 'Return a new Point object replacing specified fields with new values' - result = _self._make(map(kwds.pop, ('x', 'y'), _self)) - if kwds: - raise ValueError('Got unexpected field names: %r' % list(kwds.keys())) - return result + def _replace(_self, **kwds): + 'Return a new Point object replacing specified fields with new values' + result = _self._make(map(kwds.pop, ('x', 'y'), _self)) + if kwds: + raise ValueError('Got unexpected field names: %r' % list(kwds)) + return result <BLANKLINE> - def __getnewargs__(self): - 'Return self as a plain tuple. Used by copy and pickle.' - return tuple(self) + def __getnewargs__(self): + 'Return self as a plain tuple. Used by copy and pickle.' + return tuple(self) <BLANKLINE> - x = _property(_itemgetter(0), doc='Alias for field number 0') - y = _property(_itemgetter(1), doc='Alias for field number 1') + x = _property(_itemgetter(0), doc='Alias for field number 0') + <BLANKLINE> + y = _property(_itemgetter(1), doc='Alias for field number 1') >>> p = Point(11, y=22) # instantiate with positional or keyword arguments >>> p[0] + p[1] # indexable like the plain tuple (11, 22) @@ -867,7 +868,6 @@ a fixed-width print format: The subclass shown above sets ``__slots__`` to an empty tuple. This helps keep memory requirements low by preventing the creation of instance dictionaries. - Subclassing is not useful for adding new, stored fields. Instead, simply create a new named tuple type from the :attr:`_fields` attribute: @@ -879,6 +879,7 @@ customize a prototype instance: >>> Account = namedtuple('Account', 'owner balance transaction_count') >>> default_account = Account('<owner name>', 0.0, 0) >>> johns_account = default_account._replace(owner='John') + >>> janes_account = default_account._replace(owner='Jane') Enumerated constants can be implemented with named tuples, but it is simpler and more efficient to use a simple class declaration: diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index b429599..d4e8ed6 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -265,7 +265,7 @@ class {typename}(tuple): 'Return a new {typename} object replacing specified fields with new values' result = _self._make(map(kwds.pop, {field_names!r}, _self)) if kwds: - raise ValueError('Got unexpected field names: %r' % kwds.keys()) + raise ValueError('Got unexpected field names: %r' % list(kwds)) return result def __getnewargs__(self): @@ -309,18 +309,17 @@ def namedtuple(typename, field_names, verbose=False, rename=False): # generating informative error messages and preventing template injection attacks. if isinstance(field_names, str): field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas - field_names = tuple(map(str, field_names)) + field_names = list(map(str, field_names)) if rename: - names = list(field_names) seen = set() - for i, name in enumerate(names): - if (not all(c.isalnum() or c=='_' for c in name) or _iskeyword(name) + for index, name in enumerate(field_names): + if (not all(c.isalnum() or c=='_' for c in name) + or _iskeyword(name) or not name or name[0].isdigit() or name.startswith('_') or name in seen): - names[i] = '_%d' % i + field_names[index] = '_%d' % index seen.add(name) - field_names = tuple(names) - for name in (typename,) + field_names: + for name in [typename] + field_names: if not all(c.isalnum() or c=='_' for c in name): raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name) if _iskeyword(name): @@ -338,9 +337,9 @@ def namedtuple(typename, field_names, verbose=False, rename=False): # Fill-in the class template class_definition = _class_template.format( typename = typename, - field_names = field_names, + field_names = tuple(field_names), num_fields = len(field_names), - arg_list = repr(field_names).replace("'", "")[1:-1], + arg_list = repr(tuple(field_names)).replace("'", "")[1:-1], repr_fmt = ', '.join(_repr_template.format(name=name) for name in field_names), field_defs = '\n'.join(_field_template.format(index=index, name=name) for index, name in enumerate(field_names)) |