New python syntax I was previously unaware of

This post documents the new syntax features I learned about while reading cpython internals.

You can create more than one context manager on a single line.

So for example Shaken Fist contains code like this:

with open(path + '.new', 'w') as o:
    with open(path, 'r') as i:
        ...

That can now be written like this:

with open(path + '.new', 'w') as o, open(path, 'r') as i:
    ...

 

You can assign values in a while statement, but only one.

Instead of this:

d = f.read(8000) while f: ... d = f.read(8000)

You can write this:

while d := f.read(8000):
    ...

But unfortunately this doesn’t work:

while a, b := thing():
    ...

 

You can use underscores as commands in long numbers to make them easier to read.

For example, you can write 1000000 or 1_000_000 and they both mean the same thing.

 

You can refer to positional arguments by name, but you can also disable that.

I didn’t realise that this was valid python:

def foo(bar=None):
    print(bar)

foo(bar='banana')

You can turn it off with a forward slash in the argument list though, which should separate positional arguments from named arguments:

def foo(bar, /, extra=None):
    print(bar)
    print(extra)

foo('banana', extra='frog')

The above example will work, whereas this wont:

>>> foo(bar='banana', extra='frog')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() got some positional-only arguments passed as keyword arguments: 'bar'

 

yield from lets you “delegate” yielding values in an interator

This one is interesting. So if you find yourself writing code like this:

def get_things():
    while thing in find_one_category():
        yield thing

    while thing in find_another_category():
        yield thing

Then you can instead write that as:

def get_things():
    yield from find_one_category()
    yield from find_another_category()

Which is much nicer.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.