Bitbucket is a code hosting site with unlimited public and private repositories. We're also free for small teams!


print, format, and %, evolved.

Q: It's been forty years since C introduced printf() and the basic formatted printing of positional parameters. Isn't it time for an upgrade?

A: Yes! ZOMG, yes!

say supplements or replaces Python's print statement/function, format function/method, and % string interpolation operator with simpler, higher-level facilities. For example:

from say import say

x, nums, name = 12, list(range(4)), 'Fred'

say("There are {x} things.")
say("Nums has {len(nums)} items: {nums}")
say("Name: {name!r}")


There are 12 things.
Nums has 4 items: [0, 1, 2, 3]
Name: 'Fred'

At this level, say is basically a simpler, nicer recasting of:

from __future__ import print_function

print("There are {0} things.".format(x))
print("Nums has {0} items: {1}".format(len(nums), nums))
print("Name: {0!r}".format(name))

(And yes, you really do need that import and the numerical sequencing of {} format specs if you want code that works correctly from Python 2.6 forward from a single code base.)

The more items being printed, and the more complicated the format invocation, the more valuable this simple inline specification becomes.

One final example:

say("Name: {name:style=blue+underline}")
say("Age:  {age:style=blue}")

Beyond DRY, Pythonic templates that piggyback the Python's well-proven format() method, syntax, and underlying engine, say's virtues include:

  • A single output mechanism identical and compatible across Python 2 and Python 3.
  • A companion fmt() object for string formatting.
  • Higher-order line formatting such as line numbering, indentation, and wrapping built in.
  • Convenient methods for common formatting items such as titles, horizontal separators, and vertical whitespace.
  • Easy styled output, including ANSI colors and user-defined styles and text transforms.
  • Easy output to one or more files, with no additional code.
  • Super-duper template/text aggregator objects for easily building, reading, and writing multi-line texts.

Take it for a test drive today! See also the full documentation at Read the Docs.

Recent activity

Jonathan Eunice

Jonathan Eunice pushed 1 commit to jeunice/say

7593aa4 - Fixed bug with quoted style names. Added tests. Tweaked docs. Prepared some for future Style objects and auto-joining of collections.
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.