You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Mar 23, 2023. It is now read-only.
I read that you don't want to have things execing. Here's a rough sketch of what a namedtuple might look like without exec.
class NamedTuple(tuple):
'tuple with named attribute aliases for elements'
def __new__(cls, *args, **kwds):
'Create new instance of {typename}'
excess = set(kwds) - set(cls._fields)
if excess:
raise TypeError('Unexpected keyword arguments %r' % excess)
kwds = sorted(kwds.items(), key=lambda pair: cls._fields.index(pair[0]))
return tuple.__new__(cls, args + tuple(v for k, v in kwds))
@classmethod
def _make(cls, iterable, new=tuple.__new__, len=len):
'Make a new {typename} object from a sequence or iterable'
n = len(cls._fields)
result = new(cls, iterable)
if len(result) != n:
raise TypeError('Expected %d arguments, got %d' % (n, len(result)))
return result
def __repr__(self):
'Return a nicely formatted representation string'
names = self._fields
values = [getattr(self, name) for name in self._fields]
attrstring = ', '.join('%s=%r' % (k, v) for k, v in zip(names, values))
return '%s(%s)' % (type(self).__name__, attrstring)
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 {typename} object replacing specified fields with new values'
result = _self._make(map(kwds.pop, _self._fields, _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
def namedtuple(typename, field_names, verbose=False, rename=False):
"""Returns a new subclass of tuple with named fields.
>>> Point = namedtuple('Point', ['x', 'y'])
>>> Point.__doc__ # docstring for the new class
'Point(x, y)'
>>> p = Point(11, y=22) # instantiate with positional args or keywords
>>> p[0] + p[1] # indexable like a plain tuple
33
>>> x, y = p # unpack like a regular tuple
>>> x, y
(11, 22)
>>> p.x + p.y # fields also accessible by name
33
>>> d = p._asdict() # convert to a dictionary
>>> d['x']
11
>>> Point(**d) # convert from a dictionary
Point(x=11, y=22)
>>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
Point(x=100, y=22)
"""
# Validate the field names. At the user's option, either generate an error
# message or automatically replace the field name with a valid name.
if isinstance(field_names, basestring):
field_names = field_names.replace(',', ' ').split()
field_names = map(str, field_names)
typename = str(typename)
if rename:
seen = set()
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):
field_names[index] = '_%d' % index
seen.add(name)
for name in [typename] + field_names:
if type(name) != str:
raise TypeError('Type names and field names must be strings')
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):
raise ValueError('Type names and field names cannot be a '
'keyword: %r' % name)
if name[0].isdigit():
raise ValueError('Type names and field names cannot start with '
'a number: %r' % name)
seen = set()
for name in field_names:
if name.startswith('_') and not rename:
raise ValueError('Field names cannot start with an underscore: '
'%r' % name)
if name in seen:
raise ValueError('Encountered duplicate field name: %r' % name)
seen.add(name)
if verbose:
raise NotImplementedError('verbose mode irrelevant to this implementation')
bases = (NamedTuple,)
field = lambda i: property(itemgetter(i), doc='Alias for field number %d' % i)
attributes = {name: field(i) for i, name in enumerate(field_names)}
attributes['__slots__'] = ()
attributes['_fields'] = tuple(field_names)
attributes['__doc__'] = '%s(%s)' % (typename, str(field_names).replace("'", '')[1:-1])
result = type(typename, bases, attributes)
return result
I copy-pasted from the CPython stdlib, deleted the exec and fiddled until it seemed to work.
The text was updated successfully, but these errors were encountered:
I read that you don't want to have things
exec
ing. Here's a rough sketch of what a namedtuple might look like withoutexec
.I copy-pasted from the CPython stdlib, deleted the
exec
and fiddled until it seemed to work.The text was updated successfully, but these errors were encountered: