PythonMastery
reference 5 min read · lesson 7 of 25 in Reference

Python F-String & Format Spec Cheat Sheet

1 · The lesson

read

An f-string is a string with f before the quotes. Python runs the code inside each pair of {} and puts the result into the text. After a colon you can add a format spec: a short code that says how to show the value, such as 2 decimal places or a width of 10 characters. For the full tutorial, see F-strings.


1. Put values in

Any Python expression works inside the braces: a variable, a sum, a method call, an index.

python
name, n, price = "Ada", 42, 1234.5
f"Hi {name}"                          # 'Hi Ada'
f"{n + 1} items"                      # '43 items'
f"{name.upper()}"                     # 'ADA'
f"{name[0]}."                         # 'A.'
f"{'odd' if n % 2 else 'even'}"       # 'even'  (an if/else inside the braces)
f"{[1, 2]}"                           # '[1, 2]'  (a list looks the same as when you print it)

2. The parts of a format spec

The parts go in this fixed order. Every part is optional.

python
{value:[fill][align][sign][#][0][width][,][.precision][type]}
PartExampleWhat it does
fill*The character used for padding (a space by default)
align< > ^ =Left, right, centre, or padding between the sign and the digits
sign+ or a spaceShow a + before positive numbers, or a space
##Add a prefix: 0x for hex, 0b for binary, 0o for octal
00Pad a number with zeros
width10The smallest number of characters to use
, or _,Put a separator between thousands
.precision.2Decimal places for a number. The most characters for text
typef d e x %How to show the number: decimals, whole number, scientific, hex, percent

3. Width and alignment

Text lines up on the left by default, and numbers line up on the right. A precision on text cuts it short.

python
f"[{name:<6}]"        # '[Ada   ]'  (left)
f"[{name:>6}]"        # '[   Ada]'  (right)
f"[{name:^7}]"        # '[  Ada  ]'  (centre)
f"[{name:*^7}]"       # '[**Ada**]'  (the fill character goes before < > ^)
f"[{n:6}]"            # '[    42]'
f"[{-n:=6}]"          # '[-   42]'  (= puts the padding between the sign and the digits)
f"{name:.2}"          # 'Ad'
f"{'Lovelace':.3}…"   # 'Lov…'  (cut a long name to fit a column)
+ setup added so this can run · re-runs 1 earlier block on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

name = _AutoMock('name')
n = 1

# Earlier blocks on this page that this one builds on, re-run quietly first.
_pm_earlier = [
    'name, n, price = "Ada", 42, 1234.5\nf"Hi {name}"                          # \'Hi Ada\'\nf"{n + 1} items"                      # \'43 items\'\nf"{name.upper()}"                     # \'ADA\'\nf"{name[0]}."                         # \'A.\'\nf"{\'odd\' if n % 2 else \'even\'}"       # \'even\'  (an if/else inside the braces)\nf"{[1, 2]}"                           # \'[1, 2]\'  (a list looks the same as when you print it)',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

4. Decimals and big numbers

python
f"{3.14159:.2f}"      # '3.14'  (f: a fixed number of decimal places)
f"{2.5:.0f}"          # '2'  (a half rounds to the even number, like round())
f"{price:,.2f}"       # '1,234.50'
f"{1000000:_}"        # '1_000_000'
f"{0.256:.1%}"        # '25.6%'  (% multiplies by 100 for you)
f"{6.022e23:.3e}"     # '6.022e+23'  (scientific notation)
f"{0.000123:.2g}"     # '0.00012'  (g: 2 significant figures)
f"{price:10.2f}"      # '   1234.50'  (the width of 10 includes the point and the decimals)
+ setup added so this can run · re-runs 1 earlier block on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

price = _AutoMock('price')

# Earlier blocks on this page that this one builds on, re-run quietly first.
_pm_earlier = [
    'name, n, price = "Ada", 42, 1234.5\nf"Hi {name}"                          # \'Hi Ada\'\nf"{n + 1} items"                      # \'43 items\'\nf"{name.upper()}"                     # \'ADA\'\nf"{name[0]}."                         # \'A.\'\nf"{\'odd\' if n % 2 else \'even\'}"       # \'even\'  (an if/else inside the braces)\nf"{[1, 2]}"                           # \'[1, 2]\'  (a list looks the same as when you print it)',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

5. Signs and zero padding

A 0 just before the width pads a number with zeros. The zeros go after the sign.

python
f"{n:+}"              # '+42'  (always show the sign)
f"{n: }"              # ' 42'  (a space where the + would go)
f"{7:03}"             # '007'
f"{-7:04}"            # '-007'
f"{3.14:07.2f}"       # '0003.14'  (the width counts the point too)
f"INV-{n:06}"         # 'INV-000042'  (invoice numbers with a fixed length)
+ setup added so this can run · re-runs 1 earlier block on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

n = _AutoMock('n')

# Earlier blocks on this page that this one builds on, re-run quietly first.
_pm_earlier = [
    'name, n, price = "Ada", 42, 1234.5\nf"Hi {name}"                          # \'Hi Ada\'\nf"{n + 1} items"                      # \'43 items\'\nf"{name.upper()}"                     # \'ADA\'\nf"{name[0]}."                         # \'A.\'\nf"{\'odd\' if n % 2 else \'even\'}"       # \'even\'  (an if/else inside the braces)\nf"{[1, 2]}"                           # \'[1, 2]\'  (a list looks the same as when you print it)',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

6. Binary, octal and hexadecimal

python
f"{255:x}"                       # 'ff'  (X gives upper case: FF)
f"{255:#x}"                      # '0xff'  (# adds the 0x prefix)
f"{255:#010x}"                   # '0x000000ff'  (# with 0 and a width of 10)
f"{10:b}"                        # '1010'  (binary)
f"{10:o}"                        # '12'  (octal)
f"{5:08b}"                       # '00000101'  (a full byte: 8 binary digits)
f"#{255:02x}{0:02x}{128:02x}"    # '#ff0080'  (red, green and blue as a hex colour)

7. Dates and times

For a date or a time, the format spec uses the same codes as strftime(): %Y is the year, %m the month, %d the day. See the datetime cheat sheet for the full list.

python
from datetime import datetime
d = datetime(2026, 3, 14, 9, 30)
f"{d:%Y-%m-%d}"       # '2026-03-14'
f"{d:%d %b %Y}"       # '14 Mar 2026'
f"{d:%A, %H:%M}"      # 'Saturday, 09:30'
f"{d:%I:%M %p}"       # '09:30 AM'  (a 12-hour clock)
fmt = "%d/%m/%y"
f"{d:{fmt}}"          # '14/03/26'  (the format kept in a variable)
f"{d.day}/{d.month}"  # '14/3'  (no zero padding, unlike %d)

8. Debugging

Put = after the expression and the f-string shows the expression too. The = form is a quick way to see values while you look for a bug.

python
f"{n=}"               # 'n=42'
f"{n * 2 = }"         # 'n * 2 = 84'  (the spaces around = are kept)
f"{price=:,.1f}"      # 'price=1,234.5'  (a format spec still works after the =)
f"{name!r}"           # "'Ada'"  (!r uses repr(), which shows the quotes)
f"{name=}"            # "name='Ada'"
f"{'café'!a}"         # "'caf\\xe9'"  (!a uses ascii(), which escapes letters like é)
f"{name!r:>8}"        # "   'Ada'"  (the ! part comes first, then the colon)
+ setup added so this can run · re-runs 1 earlier block on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

n = 1
price = _AutoMock('price')
name = _AutoMock('name')

# Earlier blocks on this page that this one builds on, re-run quietly first.
_pm_earlier = [
    'name, n, price = "Ada", 42, 1234.5\nf"Hi {name}"                          # \'Hi Ada\'\nf"{n + 1} items"                      # \'43 items\'\nf"{name.upper()}"                     # \'ADA\'\nf"{name[0]}."                         # \'A.\'\nf"{\'odd\' if n % 2 else \'even\'}"       # \'even\'  (an if/else inside the braces)\nf"{[1, 2]}"                           # \'[1, 2]\'  (a list looks the same as when you print it)',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

9. Nested fields

A format spec can contain its own {}, so the width, the precision or the whole spec can come from a variable.

python
w, p, fill = 10, 3, "*"
f"{3.14159:{w}.{p}f}"      # '     3.142'
f"{'Ada':{fill}^{w}}"      # '***Ada****'
spec = ",.2f"
f"{1234.5:{spec}}"         # '1,234.50'

10. Braces, quotes and long lines

To show a real { or }, write it twice. Since Python 3.12 you can use the same quotes and a backslash inside the braces. In older versions, use the other kind of quote.

python
f"{{n}} is {n}"                        # '{n} is 42'
f"{name.replace('a', 'o')}"            # 'Ado'
msg = (f"Name: {name}\n"
       f"Age:  {n}")                   # two strings side by side join into one
report = f"""Name: {name}
Score: {97:>5}/100"""                  # triple quotes keep the line breaks
print(report)
+ setup added so this can run · re-runs 1 earlier block on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

n = _AutoMock('n')
name = _AutoMock('name')

# Earlier blocks on this page that this one builds on, re-run quietly first.
_pm_earlier = [
    'name, n, price = "Ada", 42, 1234.5\nf"Hi {name}"                          # \'Hi Ada\'\nf"{n + 1} items"                      # \'43 items\'\nf"{name.upper()}"                     # \'ADA\'\nf"{name[0]}."                         # \'A.\'\nf"{\'odd\' if n % 2 else \'even\'}"       # \'even\'  (an if/else inside the braces)\nf"{[1, 2]}"                           # \'[1, 2]\'  (a list looks the same as when you print it)',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier
text
Name: Ada
Score:    97/100

11. Tables and reports

Use the same widths for the header and for each row. Then the columns line up.

python
rows = [("tea", 3.5), ("cake", 12.0)]
print(f"{'Item':<8}{'Cost':>8}")
for item, cost in rows:
    print(f"{item:<8}{cost:>8,.2f}")
print(f"{'':-^16}")
print(f"{'Total':.<9}{15.5:>7,.2f}")
python
Item        Cost
tea         3.50
cake       12.00
----------------
Total....  15.50

12. When not to use an f-string

An f-string runs where you write it, so it cannot be a template kept for later. For a template stored in a variable or a file, use str.format(). For logging, pass the values as arguments: the logger fills them in only if it writes the line.

python
tpl = "{name} has {n} messages"
tpl.format(name="Hedy", n=3)          # 'Hedy has 3 messages'
format(1234.5, ",.2f")                # '1,234.50'  (the same spec, without a string around it)

Common mistakes

Forgetting the f. "Hi {name}" prints the braces exactly as typed. Write f"Hi {name}".

A number spec on text. f"{name:.2f}" raises ValueError: Unknown format code 'f' for object of type 'str'. If the text holds a number, convert it first: f"{float('3.5'):.2f}".

Expecting exact rounding. A float is stored in binary, so some values are a tiny bit smaller than they look:

python
f"{2.675:.2f}"        # '2.67'

Use the decimal module for money.

Expecting the width to cut text. The width is a minimum, so long text is never cut. Add a precision to cut it:

python
f"{'Lovelace':5}"     # 'Lovelace'
f"{'Lovelace':.5}"    # 'Lovel'

A comma outside the spec. f"{n,}" makes a tuple, because the comma comes before the colon:

python
f"{n,}"               # '(42,)'
f"{n:,}"              # '42'
+ setup added so this can run · re-runs 1 earlier block on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

n = _AutoMock('n')

# Earlier blocks on this page that this one builds on, re-run quietly first.
_pm_earlier = [
    'name, n, price = "Ada", 42, 1234.5\nf"Hi {name}"                          # \'Hi Ada\'\nf"{n + 1} items"                      # \'43 items\'\nf"{name.upper()}"                     # \'ADA\'\nf"{name[0]}."                         # \'A.\'\nf"{\'odd\' if n % 2 else \'even\'}"       # \'even\'  (an if/else inside the braces)\nf"{[1, 2]}"                           # \'[1, 2]\'  (a list looks the same as when you print it)',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

Parts in the wrong order. f"{n:5+}" raises ValueError. The sign comes before the width: f"{n:+5}".

Doing maths with the result. An f-string gives text, so f"{price:.2f}" + 1 raises TypeError. Keep the number for calculations and format it only when you show it.

.2 without a type. Without f, the precision means significant figures, not decimal places:

python
f"{price:.2}"         # '1.2e+03'
f"{price:.2f}"        # '1234.50'
+ setup added so this can run · re-runs 1 earlier block on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

price = _AutoMock('price')

# Earlier blocks on this page that this one builds on, re-run quietly first.
_pm_earlier = [
    'name, n, price = "Ada", 42, 1234.5\nf"Hi {name}"                          # \'Hi Ada\'\nf"{n + 1} items"                      # \'43 items\'\nf"{name.upper()}"                     # \'ADA\'\nf"{name[0]}."                         # \'A.\'\nf"{\'odd\' if n % 2 else \'even\'}"       # \'even\'  (an if/else inside the braces)\nf"{[1, 2]}"                           # \'[1, 2]\'  (a list looks the same as when you print it)',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

See also

Practice this

on practicepython.in

Short exercises that run in your browser and tell you what your code did, as well as whether a test passed.

Found this useful? Share it with a friend who’s learning Python.