[Tutor] What are the benefits of template or abstract base classes?
Peter Otten
__peter__ at web.de
Mon Jun 8 16:59:50 EDT 2020
boB Stepp wrote:
> On Mon, Jun 8, 2020 at 7:52 AM Peter Otten <__peter__ at web.de> wrote:
>>
>> boB Stepp wrote:
>>
>> > Now in "4.2 Inheritance" at
>> > https://dabeaz-course.github.io/practical->> > python/Notes/04_Classes_objects/02_Inheritance.html
>> >
>> > class TableFormatter:
>> > def headings(self, headers):
>> > '''
>> > Emit the table headings.
>> > '''
>> > raise NotImplementedError()
>> >
>> > def row(self, rowdata):
>> > '''
>> > Emit a single row of table data.
>> > '''
>> > raise NotImplementedError()
>> >
>> > with the comment:
>> >
>> > "This class does nothing
>>
>> > What are your thoughts?
>>
>> Dunno. Maybe writing code that does nothing is an art form, like poems or
>> songs... and mypy is your arbiter elegantiarum.
>
> Totally unexpected, quirky response! Who shall reign supreme in
> directing my cyber-court: Black, MyPy or Pylint? Pylint critiques
> seemingly every choice, but will back down if challenged. MyPy only
> judges a subset of cyberlife. And Black judges with an iron hand.
> Perhaps off with him to the Coliseum fights to perish unless further
> deemed worthy?
> ~(:>))
>
I don't know Black; with pylint you can cheat a little and get a score of 10
for your perfect code, or you can cheat some more and get a score of 10 for
your heap of crap.
mypy on the other hand is open-ended.
Start with TableFormatter, do you want to feed it Any? Of course not, so
print_table(table: Table, formatter: TableFormatter)
We've already established that the table consists of header and rows
class Header:
column_headers: Sequence[ColumnHeader]
class Rows:
rows: Iterator[Row]
class Row:
fields: Sequence[Field]
class Field:
def format(format: FieldFormat) -> str
class StrField, FloatField, DatetimeField, YouNameItField,...
Table:
rows: Rows
header: Header
That looks safe except that we stated that fields are formatted as str.
What if in addition to csv and text we want to write a binary format?
class Field:
def format(format: FieldFormat) -> SerializedField
We are starting to get robust. We just need to come up with a FieldFormat
that works for all subclasses. That can't be hard, so let's look elsewhere.
David used short strings to specify the Formatter -- not very robust, and
Python has enums since ... when? So
class TableFormatterType(enum.Enum):
text = "txt"
csv = "csv"
Not as good as the http guys with their Referer, but still nice.
Having another glimpse at our zoo of fields, how can we instantiate the
right subclass? We certainly need a
RowFieldFactory
and a
ColumnHeaderFactory.
While we're at it, a
TableFormatterFactory
to cope with our CSVTableFormatter, and TextTableFormatter is de rigueur.
Are we done? Oh dear, do you think our table springs into existence out of
nowhere?
I'll leave the details of the TableBuilder, or, let's be precise,
FormatableTableBuilder (or is it PrintableFormatableTableBuilder?) as an
exercise for the reader...
That said, I feel a bit uneasy about the FieldFormat, we should do it right
and use a FieldFormatter instead. That gives us flexibility; one formatter
per field type, composable for width, alignment, color, font,
all governed by a nice little FieldFormatterFactory...
More information about the Tutor
mailing list