Two-Dimensional Expression Layout
Steve D'Aprano
steve+python at pearwood.info
Sat Aug 20 21:13:19 EDT 2016
On Sun, 21 Aug 2016 08:22 am, Lawrence D’Oliveiro wrote:
> Another example, from <https://github.com/ldo/qahirah>: the sequence of
> values is laid out to allow easy additions/modifications in future.
When replying, I normally try to trim unnecessary code snippets down to the
critical line or two, but in this case I think that it is important that I
leave Lawrence's example in place in all its glory. See below for further
comments.
> for \
> symname, funcname \
> in \
> (
> ("FC_FONT", "ft_font_face_create_for_ft_face"),
> ("FT_FONT", "ft_font_face_create_for_pattern"),
> ("IMAGE_SURFACE", "image_surface_create"),
> # TODO: MIME_SURFACE, OBSERVER_SURFACE?
> ("PDF_SURFACE", "pdf_surface_create"),
> ("PNG_FUNCTIONS", "surface_write_to_png"),
> ("PS_SURFACE", "ps_surface_create"),
> ("RECORDING_SURFACE", "recording_surface_create"),
> ("SCRIPT_SURFACE", "script_create"),
> ("SVG_SURFACE", "svg_surface_create"),
> {"USER_FONT", "user_font_face_create"},
> ) \
> :
> setattr \
> (
> HAS,
> symname,
> hasattr(cairo, "cairo_" + funcname)
> )
> #end for
>
> As a bonus, this also counts as an example of data-driven programming.
Is the subtle bug in your code also a bonus?
If this bug has never bit you, it will when you try to run it under a
version of Python with hash randomization turned on. (3.5 and above, I
think.) You're (accidentally, I presume) relying on the set:
{"USER_FONT", "user_font_face_create"}
always iterating in the same order. It won't. I assume that's just a typo
and it's meant to be a tuple.
Your idiosyncratic layout obscures what should be a standard two-line for
loop in a jumble of unneeded backslashes, almost empty lines and
indentation.
for symname, funcname in FONT_TABLE:
setattr(HAS, symname, hasattr(cairo, "cairo_" + funcname))
where FONT_TABLE is defined previously. If you don't want to give this its
own name, you can embed it in the for loop:
for symname, funcname in [
("FC_FONT", "ft_font_face_create_for_ft_face"),
("FT_FONT", "ft_font_face_create_for_pattern"),
("IMAGE_SURFACE", "image_surface_create"),
# TODO: MIME_SURFACE, OBSERVER_SURFACE?
("PDF_SURFACE", "pdf_surface_create"),
("PNG_FUNCTIONS", "surface_write_to_png"),
("PS_SURFACE", "ps_surface_create"),
("RECORDING_SURFACE", "recording_surface_create"),
("SCRIPT_SURFACE", "script_create"),
("SVG_SURFACE", "svg_surface_create"),
("USER_FONT", "user_font_face_create"),
]:
setattr(HAS, symname, hasattr(cairo, "cairo_" + funcname))
There's no need to arbitrarily indent parts of expressions to "allow easy
additions" in the future: it is already easy to add new tuples to the
table, or modify existing ones.
--
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
More information about the Python-list
mailing list