Last active
December 17, 2015 01:38
-
-
Save majgis/5529422 to your computer and use it in GitHub Desktop.
A defaultnamedtuple which creates a namedtuple with default values when none are given.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" Additional collections to augment Python's collections module. | |
""" | |
from collections import namedtuple | |
def defaultnamedtuple( | |
typename, | |
field_names, | |
verbose=False, | |
rename=False, | |
default_factory=None | |
): | |
"""A factory for namedtuples with default values similar to defaultdict. | |
The default_factory is a callable which returns default values. All | |
other functionality matches namedtuple. When default_factory is None, the | |
default, the defaultnamedtuple acts exactly the same as a namedtuple. | |
""" | |
tuple_class = namedtuple(typename, field_names, verbose, rename) | |
class sub_tuple_class(tuple_class): | |
def __new__(self, *args, **kwargs): | |
if default_factory: | |
missing_args = field_names[len(args):] | |
for missing_arg in missing_args: | |
if not missing_arg in kwargs: | |
kwargs[missing_arg] = default_factory() | |
return super(sub_tuple_class, self).__new__(self, *args, **kwargs) | |
return sub_tuple_class | |
if __name__ == '__main__': | |
import unittest | |
class defaultnamedtupleTestCase(unittest.TestCase): | |
""" A test case for defaultnamedtuple class factory""" | |
def setUp(self): | |
"""Initial setup for all tests""" | |
self.class_str = 'Test(x=0, y=0, z=0)' | |
self.class_name = 'Test' | |
self.field_names = ['x', 'y', 'z'] | |
self.default_value = 0 | |
self.test_default = defaultnamedtuple( | |
self.class_name, | |
self.field_names, | |
default_factory=lambda:self.default_value | |
) | |
self.test_no_default = defaultnamedtuple( | |
self.class_name, | |
self.field_names | |
) | |
self.reference = namedtuple(self.class_name, self.field_names) | |
def testNoArgsOrKwargs(self): | |
"""Test defaultnamedtuple with no args or kwargs""" | |
a = self.test_default() | |
b = self.reference( | |
self.default_value, | |
self.default_value, | |
self.default_value | |
) | |
self.assertEqual(a, b) | |
def testSomeArgs(self): | |
"""Test defaultnamedtuple with some but not all args given.""" | |
a = self.test_default(1, 1) | |
b = self.reference( | |
1, | |
1, | |
self.default_value | |
) | |
self.assertEqual(a, b) | |
def testSomeKwargs(self): | |
"""Test defaultnamedtuple with some but not all kwargs given.""" | |
a = self.test_default(x=1, z=1) | |
b = self.reference( | |
x=1, | |
y=self.default_value, | |
z=1 | |
) | |
self.assertEqual(a, b) | |
unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment