3. Blueprint¶
The namedtuplex package provides extended named tuples with inheritance and function-style defaults for fields. The parameter passing is designed as member variables of the derived classes implemented by the meta class NamedTupleXABCMeta. The application of the default values relies on the implementation of the actual factory - the optional parameter tuplefactory. The default factory is namedtupledefs.namedtuple with support for default values.
For details on the implemented design refer to “The Implementation Basics of Classes” and “The SW-Design of namedtuplex”.
The provided function namedtuplex could be used as a drop-in replacement of the namedtupledefs [namedtupledefs] and standard namedtuple [namedtuple] class factory as well as the namedtuple_with_abc implementation by Jan Kaliszewski [JANKALI] [NAMEDTUPLEABC] - when used with the standard parameters only. The receipt published by Jan Kaliszewski [NAMEDTUPLEABC] served as a base for the namedtuplex.
3.1. Classes¶
Just a reminder - in Python anything is a class.
3.1.1. Simple Named Tuple Class¶
Create a simple class:
from __future__ import print_function from namedtuplex.abc import NamedTupleXABC, ABC class MyClass(NamedTupleXABC): _fields = ('a', 'b', ) # defines the fields of the namedtuple pass assert issubclass(MyClass, ABC) mynamedtuple = MyClass(11, 22) assert mynamedtuple[0] == 11 assert mynamedtuple[1] == 22 print("OK")
3.1.2. Symbolic Field Names¶
Alternative symbolic names for the fields of the tuple.
from __future__ import print_function from namedtuplex.abc import NamedTupleXABC, ABC class MyClass(NamedTupleXABC): _fields = ('a', 'b', ) # defines the symbolic names pass assert issubclass(MyClass, ABC) mynamedtuple = MyClass(11, 22) assert mynamedtuple[0] == 11 assert mynamedtuple[1] == 22 assert mynamedtuple[0] == mynamedtuple.a assert mynamedtuple[1] == mynamedtuple.b print("OK")
3.1.3. Inheritance¶
Inheritance of abstract and non-abstract classes.
from __future__ import print_function from namedtuplex.abc import NamedTupleXABC, ABC class MyClass(NamedTupleXABC): _fields = ('a', 'b', ) pass assert issubclass(MyClass, ABC) class MyClassDerived(MyClass): _fields = MyClass._fields + ('c',) # the inheritance of fields requires manual coding pass assert issubclass(MyClassDerived, ABC) mynamedtuple0 = MyClass(11, 22) mynamedtuple01= MyClassDerived(11, 22, 33) print("OK")
For the concept see Class Concept of namedtuplex.abc.
3.1.4. Abstract Inheritance¶
Creates an abstract tuple class in accordance to [PEP3119], see also [abc].
Example with inherited attribute from a custom abstract class.
from __future__ import print_function from namedtuplex.abc import NamedTupleXABC, ABC class MyClassABC0(NamedTupleXABC): # abstract class typeid = 4711 # standard inheritance for typeid class MyClassABC1(MyClassABC0): # abstract class formatid = 'xyz' # standard inheritance for formid class MyClass(MyClassABC1): # non-abstract class _fields = ('a', 'b') # triggered by _fields def __str__(self): return "%d(%s): %s / %s" % (self.typeid, self.formatid, self[0], self[1]) mynamedtuple0 = MyClass(11, 22) print(mynamedtuple0)
For the concept see Inheritance of Abstract Classes.
3.1.5. Mixin¶
The use of the the generated tuple class as mixin.
from __future__ import print_function from namedtuplex.abc import NamedTupleXABC class MyClassABC(NamedTupleXABC): # abstract class typeid = 4711 class MyBaseClass(MyClassABC): # non-abstract class _fields = ('a', 'b',) class MyOtherBaseClass(object): # non-abstract and non-tupel class def print(self): print(str(self._fields)) print(str(self)) class MyClassL(MyBaseClass, MyOtherBaseClass): pass class MyClassR(MyOtherBaseClass, MyBaseClass): pass mynamedtuple0 = MyClassL(11, 22,) mynamedtuple0.print() mynamedtuple1 = MyClassR(11, 22,) mynamedtuple1.print()
3.1.6. Default Values¶
Default values for for the fields, supports partial fields for the initialization of the generated class - similar to function arguments [PYFUNC].
from __future__ import print_function from namedtuplex.abc import NamedTupleXABC, ABC class MyClass(NamedTupleXABC): _fields = ('a', 'b', 'c', ) # defines the fields and the symbolic names mynamedtuple0 = MyClass(11, 22, fielddefaults=(('c', 33),) ) # add dynamic defaults via metaclass mynamedtuple1 = MyClass(11, fielddefaults=(( 2, 33), ('b', 22),)) # add dynamic defaults via metaclass mynamedtuple2 = MyClass(11, 55, 66, fielddefaults=(('c', 33), ( 1, 22),)) # add dynamic defaults via metaclass assert mynamedtuple0[0] == 11 assert mynamedtuple0[1] == 22 assert mynamedtuple0[2] == 33 assert mynamedtuple1[0] == 11 assert mynamedtuple1[1] == 22 assert mynamedtuple1[2] == 33 assert mynamedtuple2[0] == 11 assert mynamedtuple2[1] == 55 assert mynamedtuple2[2] == 66 print("OK")
Or the alternate static variant, which allows only one set of default values for each class:
from __future__ import print_function from namedtuplex.abc import NamedTupleXABC, ABC class MyClass(NamedTupleXABC): _fields = ('a', 'b', 'c', ) # defines the symbolic names _item_defauls = (('c', 33), (1, 22),)) mynamedtuple2 = MyClass(11, 55) assert mynamedtuple0[0] == 11 assert mynamedtuple0[1] == 55 assert mynamedtuple0[2] == 33 print("OK")