Eliminate camelcase function name
This commit is contained in:
parent
814b04600c
commit
a48a29947a
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
This module implements high-performance container datatypes. Currently,
|
This module implements high-performance container datatypes. Currently,
|
||||||
there are two datatypes, :class:`deque` and :class:`defaultdict`, and
|
there are two datatypes, :class:`deque` and :class:`defaultdict`, and
|
||||||
one datatype factory function, :func:`NamedTuple`. Python already
|
one datatype factory function, :func:`named_tuple`. Python already
|
||||||
includes built-in containers, :class:`dict`, :class:`list`,
|
includes built-in containers, :class:`dict`, :class:`list`,
|
||||||
:class:`set`, and :class:`tuple`. In addition, the optional :mod:`bsddb`
|
:class:`set`, and :class:`tuple`. In addition, the optional :mod:`bsddb`
|
||||||
module has a :meth:`bsddb.btopen` method that can be used to create in-memory
|
module has a :meth:`bsddb.btopen` method that can be used to create in-memory
|
||||||
|
@ -25,7 +25,7 @@ ordered dictionaries.
|
||||||
Added :class:`defaultdict`.
|
Added :class:`defaultdict`.
|
||||||
|
|
||||||
.. versionchanged:: 2.6
|
.. versionchanged:: 2.6
|
||||||
Added :class:`NamedTuple`.
|
Added :func:`named_tuple`.
|
||||||
|
|
||||||
|
|
||||||
.. _deque-objects:
|
.. _deque-objects:
|
||||||
|
@ -348,14 +348,14 @@ Setting the :attr:`default_factory` to :class:`set` makes the
|
||||||
|
|
||||||
.. _named-tuple-factory:
|
.. _named-tuple-factory:
|
||||||
|
|
||||||
:func:`NamedTuple` Factory Function for Tuples with Named Fields
|
:func:`named_tuple` Factory Function for Tuples with Named Fields
|
||||||
----------------------------------------------------------------
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
Named tuples assign meaning to each position in a tuple and allow for more readable,
|
Named tuples assign meaning to each position in a tuple and allow for more readable,
|
||||||
self-documenting code. They can be used wherever regular tuples are used, and
|
self-documenting code. They can be used wherever regular tuples are used, and
|
||||||
they add the ability to access fields by name instead of position index.
|
they add the ability to access fields by name instead of position index.
|
||||||
|
|
||||||
.. function:: NamedTuple(typename, fieldnames, [verbose])
|
.. function:: named_tuple(typename, fieldnames, [verbose])
|
||||||
|
|
||||||
Returns a new tuple subclass named *typename*. The new subclass is used to
|
Returns a new tuple subclass named *typename*. The new subclass is used to
|
||||||
create tuple-like objects that have fields accessable by attribute lookup as
|
create tuple-like objects that have fields accessable by attribute lookup as
|
||||||
|
@ -363,22 +363,22 @@ they add the ability to access fields by name instead of position index.
|
||||||
helpful docstring (with typename and fieldnames) and a helpful :meth:`__repr__`
|
helpful docstring (with typename and fieldnames) and a helpful :meth:`__repr__`
|
||||||
method which lists the tuple contents in a ``name=value`` format.
|
method which lists the tuple contents in a ``name=value`` format.
|
||||||
|
|
||||||
The *fieldnames* are a single string with each fieldname separated by a space
|
The *fieldnames* are a single string with each fieldname separated by whitespace
|
||||||
and/or comma (for example "x y" or "x, y"). Alternately, the *fieldnames*
|
and/or commas (for example 'x y' or 'x, y'). Alternatively, the *fieldnames*
|
||||||
can be specified as list or tuple of strings. Any valid Python identifier
|
can be specified as a list of strings (such as ['x', 'y']). Any valid
|
||||||
may be used for a fieldname except for names starting and ending with double
|
Python identifier may be used for a fieldname except for names starting and
|
||||||
underscores.
|
ending with double underscores.
|
||||||
|
|
||||||
If *verbose* is true, will print the class definition.
|
If *verbose* is true, will print the class definition.
|
||||||
|
|
||||||
*NamedTuple* instances do not have per-instance dictionaries, so they are
|
Named tuple instances do not have per-instance dictionaries, so they are
|
||||||
lightweight and require no more memory than regular tuples.
|
lightweight and require no more memory than regular tuples.
|
||||||
|
|
||||||
.. versionadded:: 2.6
|
.. versionadded:: 2.6
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
>>> Point = NamedTuple('Point', 'x y', verbose=True)
|
>>> Point = named_tuple('Point', 'x y', verbose=True)
|
||||||
class Point(tuple):
|
class Point(tuple):
|
||||||
'Point(x, y)'
|
'Point(x, y)'
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
@ -410,27 +410,35 @@ Example::
|
||||||
Named tuples are especially useful for assigning field names to result tuples returned
|
Named tuples are especially useful for assigning field names to result tuples returned
|
||||||
by the :mod:`csv` or :mod:`sqlite3` modules::
|
by the :mod:`csv` or :mod:`sqlite3` modules::
|
||||||
|
|
||||||
|
EmployeeRecord = named_tuple('EmployeeRecord', 'name, age, title, department, paygrade')
|
||||||
|
|
||||||
from itertools import starmap
|
from itertools import starmap
|
||||||
import csv
|
import csv
|
||||||
EmployeeRecord = NamedTuple('EmployeeRecord', 'name age title department paygrade')
|
|
||||||
for emp in starmap(EmployeeRecord, csv.reader(open("employees.csv", "rb"))):
|
for emp in starmap(EmployeeRecord, csv.reader(open("employees.csv", "rb"))):
|
||||||
print emp.name, emp.title
|
print emp.name, emp.title
|
||||||
|
|
||||||
When casting a single record to a *NamedTuple*, use the star-operator [#]_ to unpack
|
import sqlite3
|
||||||
|
conn = sqlite3.connect('/companydata')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
|
||||||
|
for emp in starmap(EmployeeRecord, cursor.fetchall()):
|
||||||
|
print emp.name, emp.title
|
||||||
|
|
||||||
|
When casting a single record to a named tuple, use the star-operator [#]_ to unpack
|
||||||
the values::
|
the values::
|
||||||
|
|
||||||
>>> t = [11, 22]
|
>>> t = [11, 22]
|
||||||
>>> Point(*t) # the star-operator unpacks any iterable object
|
>>> Point(*t) # the star-operator unpacks any iterable object
|
||||||
Point(x=11, y=22)
|
Point(x=11, y=22)
|
||||||
|
|
||||||
When casting a dictionary to a *NamedTuple*, use the double-star-operator::
|
When casting a dictionary to a named tuple, use the double-star-operator::
|
||||||
|
|
||||||
>>> d = {'x': 11, 'y': 22}
|
>>> d = {'x': 11, 'y': 22}
|
||||||
>>> Point(**d)
|
>>> Point(**d)
|
||||||
Point(x=11, y=22)
|
Point(x=11, y=22)
|
||||||
|
|
||||||
In addition to the methods inherited from tuples, named tuples support
|
In addition to the methods inherited from tuples, named tuples support
|
||||||
additonal methods and a read-only attribute.
|
two additonal methods and a read-only attribute.
|
||||||
|
|
||||||
.. method:: somenamedtuple.__asdict__()
|
.. method:: somenamedtuple.__asdict__()
|
||||||
|
|
||||||
|
@ -464,8 +472,8 @@ additonal methods and a read-only attribute.
|
||||||
>>> p.__fields__ # view the field names
|
>>> p.__fields__ # view the field names
|
||||||
('x', 'y')
|
('x', 'y')
|
||||||
|
|
||||||
>>> Color = NamedTuple('Color', 'red green blue')
|
>>> Color = named_tuple('Color', 'red green blue')
|
||||||
>>> Pixel = NamedTuple('Pixel', Point.__fields__ + Color.__fields__)
|
>>> Pixel = named_tuple('Pixel', Point.__fields__ + Color.__fields__)
|
||||||
>>> Pixel(11, 22, 128, 255, 0)
|
>>> Pixel(11, 22, 128, 255, 0)
|
||||||
Pixel(x=11, y=22, red=128, green=255, blue=0)'
|
Pixel(x=11, y=22, red=128, green=255, blue=0)'
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
__all__ = ['deque', 'defaultdict', 'NamedTuple']
|
__all__ = ['deque', 'defaultdict', 'named_tuple']
|
||||||
|
|
||||||
from _collections import deque, defaultdict
|
from _collections import deque, defaultdict
|
||||||
from operator import itemgetter as _itemgetter
|
from operator import itemgetter as _itemgetter
|
||||||
import sys as _sys
|
import sys as _sys
|
||||||
|
|
||||||
def NamedTuple(typename, field_names, verbose=False):
|
def named_tuple(typename, field_names, verbose=False):
|
||||||
"""Returns a new subclass of tuple with named fields.
|
"""Returns a new subclass of tuple with named fields.
|
||||||
|
|
||||||
>>> Point = NamedTuple('Point', 'x y')
|
>>> Point = named_tuple('Point', 'x y')
|
||||||
>>> Point.__doc__ # docstring for the new class
|
>>> Point.__doc__ # docstring for the new class
|
||||||
'Point(x, y)'
|
'Point(x, y)'
|
||||||
>>> p = Point(11, y=22) # instantiate with positional args or keywords
|
>>> p = Point(11, y=22) # instantiate with positional args or keywords
|
||||||
|
@ -36,6 +36,10 @@ def NamedTuple(typename, field_names, verbose=False):
|
||||||
raise ValueError('Type names and field names can only contain alphanumeric characters and underscores')
|
raise ValueError('Type names and field names can only contain alphanumeric characters and underscores')
|
||||||
if any(name.startswith('__') and name.endswith('__') for name in field_names):
|
if any(name.startswith('__') and name.endswith('__') for name in field_names):
|
||||||
raise ValueError('Field names cannot start and end with double underscores')
|
raise ValueError('Field names cannot start and end with double underscores')
|
||||||
|
if any(name[:1].isdigit() for name in field_names):
|
||||||
|
raise ValueError('Field names cannot start with a number')
|
||||||
|
if len(field_names) != len(set(field_names)):
|
||||||
|
raise ValueError('Encountered duplicate field name')
|
||||||
|
|
||||||
# Create and fill-in the class template
|
# Create and fill-in the class template
|
||||||
argtxt = repr(field_names).replace("'", "")[1:-1] # tuple repr without parens or quotes
|
argtxt = repr(field_names).replace("'", "")[1:-1] # tuple repr without parens or quotes
|
||||||
|
@ -83,10 +87,10 @@ def NamedTuple(typename, field_names, verbose=False):
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# verify that instances can be pickled
|
# verify that instances can be pickled
|
||||||
from cPickle import loads, dumps
|
from cPickle import loads, dumps
|
||||||
Point = NamedTuple('Point', 'x, y', True)
|
Point = named_tuple('Point', 'x, y', True)
|
||||||
p = Point(x=10, y=20)
|
p = Point(x=10, y=20)
|
||||||
assert p == loads(dumps(p))
|
assert p == loads(dumps(p))
|
||||||
|
|
||||||
import doctest
|
import doctest
|
||||||
TestResults = NamedTuple('TestResults', 'failed attempted')
|
TestResults = named_tuple('TestResults', 'failed attempted')
|
||||||
print TestResults(*doctest.testmod())
|
print TestResults(*doctest.testmod())
|
||||||
|
|
|
@ -1,23 +1,25 @@
|
||||||
import unittest
|
import unittest
|
||||||
from test import test_support
|
from test import test_support
|
||||||
from collections import NamedTuple
|
from collections import named_tuple
|
||||||
|
|
||||||
class TestNamedTuple(unittest.TestCase):
|
class TestNamedTuple(unittest.TestCase):
|
||||||
|
|
||||||
def test_factory(self):
|
def test_factory(self):
|
||||||
Point = NamedTuple('Point', 'x y')
|
Point = named_tuple('Point', 'x y')
|
||||||
self.assertEqual(Point.__name__, 'Point')
|
self.assertEqual(Point.__name__, 'Point')
|
||||||
self.assertEqual(Point.__doc__, 'Point(x, y)')
|
self.assertEqual(Point.__doc__, 'Point(x, y)')
|
||||||
self.assertEqual(Point.__slots__, ())
|
self.assertEqual(Point.__slots__, ())
|
||||||
self.assertEqual(Point.__module__, __name__)
|
self.assertEqual(Point.__module__, __name__)
|
||||||
self.assertEqual(Point.__getitem__, tuple.__getitem__)
|
self.assertEqual(Point.__getitem__, tuple.__getitem__)
|
||||||
self.assertRaises(ValueError, NamedTuple, 'abc%', 'def ghi')
|
self.assertRaises(ValueError, named_tuple, 'abc%', 'def ghi')
|
||||||
self.assertRaises(ValueError, NamedTuple, 'abc', 'def g%hi')
|
self.assertRaises(ValueError, named_tuple, 'abc', 'def g%hi')
|
||||||
self.assertRaises(ValueError, NamedTuple, 'abc', '__def__ ghi')
|
self.assertRaises(ValueError, named_tuple, 'abc', '__def__ ghi')
|
||||||
NamedTuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
|
self.assertRaises(ValueError, named_tuple, 'abc', 'def def ghi')
|
||||||
|
self.assertRaises(ValueError, named_tuple, 'abc', '8def 9ghi')
|
||||||
|
named_tuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
|
||||||
|
|
||||||
def test_instance(self):
|
def test_instance(self):
|
||||||
Point = NamedTuple('Point', 'x y')
|
Point = named_tuple('Point', 'x y')
|
||||||
p = Point(11, 22)
|
p = Point(11, 22)
|
||||||
self.assertEqual(p, Point(x=11, y=22))
|
self.assertEqual(p, Point(x=11, y=22))
|
||||||
self.assertEqual(p, Point(11, y=22))
|
self.assertEqual(p, Point(11, y=22))
|
||||||
|
@ -36,17 +38,17 @@ class TestNamedTuple(unittest.TestCase):
|
||||||
self.assertEqual(p.__asdict__(), dict(x=11, y=22)) # test __dict__ method
|
self.assertEqual(p.__asdict__(), dict(x=11, y=22)) # test __dict__ method
|
||||||
|
|
||||||
# verify that field string can have commas
|
# verify that field string can have commas
|
||||||
Point = NamedTuple('Point', 'x, y')
|
Point = named_tuple('Point', 'x, y')
|
||||||
p = Point(x=11, y=22)
|
p = Point(x=11, y=22)
|
||||||
self.assertEqual(repr(p), 'Point(x=11, y=22)')
|
self.assertEqual(repr(p), 'Point(x=11, y=22)')
|
||||||
|
|
||||||
# verify that fieldspec can be a non-string sequence
|
# verify that fieldspec can be a non-string sequence
|
||||||
Point = NamedTuple('Point', ('x', 'y'))
|
Point = named_tuple('Point', ('x', 'y'))
|
||||||
p = Point(x=11, y=22)
|
p = Point(x=11, y=22)
|
||||||
self.assertEqual(repr(p), 'Point(x=11, y=22)')
|
self.assertEqual(repr(p), 'Point(x=11, y=22)')
|
||||||
|
|
||||||
def test_tupleness(self):
|
def test_tupleness(self):
|
||||||
Point = NamedTuple('Point', 'x y')
|
Point = named_tuple('Point', 'x y')
|
||||||
p = Point(11, 22)
|
p = Point(11, 22)
|
||||||
|
|
||||||
self.assert_(isinstance(p, tuple))
|
self.assert_(isinstance(p, tuple))
|
||||||
|
@ -66,9 +68,9 @@ class TestNamedTuple(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_odd_sizes(self):
|
def test_odd_sizes(self):
|
||||||
Zero = NamedTuple('Zero', '')
|
Zero = named_tuple('Zero', '')
|
||||||
self.assertEqual(Zero(), ())
|
self.assertEqual(Zero(), ())
|
||||||
Dot = NamedTuple('Dot', 'd')
|
Dot = named_tuple('Dot', 'd')
|
||||||
self.assertEqual(Dot(1), (1,))
|
self.assertEqual(Dot(1), (1,))
|
||||||
|
|
||||||
def test_main(verbose=None):
|
def test_main(verbose=None):
|
||||||
|
|
|
@ -544,7 +544,7 @@ Library
|
||||||
|
|
||||||
- Added heapq.merge() for merging sorted input streams.
|
- Added heapq.merge() for merging sorted input streams.
|
||||||
|
|
||||||
- Added collections.NamedTuple() for assigning field names to tuples.
|
- Added collections.named_tuple() for assigning field names to tuples.
|
||||||
|
|
||||||
- Added itertools.izip_longest().
|
- Added itertools.izip_longest().
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue