mirror of
https://github.com/python/cpython.git
synced 2025-12-09 18:48:05 +00:00
Minor named tuple clean-ups.
This commit is contained in:
parent
fef854602b
commit
b2d0945c87
2 changed files with 42 additions and 42 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue