A deep dive into Python 3.8

Python 3.8 is a major release of Python. Here's a list of new features you need to know about.

Assignment in Expressions (PEP572)

Python now allows you to create variables inside of expressions with the “walrus” operator :=. This will enable you to assign values to a variable as part of an expression. The major benefit of this is it saves you some lines of code when you want to use, say, the value of an expression in a subsequent condition.


def f(x):


    for k in range(10000000):

        x*x*x/x+x+x+x+x

    return x

x = 2

# Reuse a value that's expensive to compute

%timeit [y := f(x), y**2, y**3]

# Without reuse

%timeit [f(x), f(x)**2, f(x)**3]

1.78 s ± 13.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

5.45 s ± 93.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

 

There are a few places where assignment expressions are not allowed, in order to avoid ambiguities or user confusion. See: Exceptional Cases

 

Positional-only parameters (PEP 570)

This one is confusing a special marker, /, can now be used when defining a method’s arguments to specify that the function only accepts positional arguments on the left of the marker. Keyword-only arguments have been available in Python with the * marker in functions, and addition of / marker for positional-only arguments improves the language’s consistency and allows for robust API design.

def prelaunch_func(foo, bar, baz=None):

    print(f"\nFoo:{foo}\nBar:{bar}\nBaz:{baz}")

 

def pep570_func(foo, /, bar, baz=None):

    print(f"\nFoo:{foo}\nBar:{bar}\nBaz:{baz}")

 

The / in the call signature of pep570_func denotes where the positional-only args end.

 

prelaunch_func(foo=1, bar=2, baz=3)

Foo:1

Bar:2

Baz:3

# Violating positional-only

pep570_func(foo=1, bar=2, baz=3)

---------------------------------------------------------------------------

 

TypeError                                 Traceback (most recent call last)

 

<ipython-input-4-9e9851275486> in <module>

      1 # Violating positional-only

----> 2 pep570_func(foo=1, bar=2, baz=3)

 

 

TypeError: pep570_func() got some positional-only arguments passed as keyword arguments: 'foo'

# This is fine, as the bar is right of the "/" in the call signature

pep570_func(1, bar=2, baz=3)

Foo:1

Bar:2

Baz:3

# This was wrong before PEP-570 of course

pep570_func(foo=1, 2, baz=3)

  File "<ipython-input-6-adcd14865e94>", line 2

    pep570_func(foo=1, 2, baz=3)

                       ^

SyntaxError: positional argument follows keyword argument

What I like best about this PEP is that you can also have positional-only args with default values, as shown here:

def pep570_func(foo, bar=None, baz=1, /):

    print(f"\nFoo:{foo}\nBar:{bar}\nBaz:{baz}")

 

pep570_func(10)

Foo:10

Bar:None

Baz:1

 

# But don't mistake them for kwargs

pep570_func(10, bar=1)

---------------------------------------------------------------------------

 

TypeError                                 Traceback (most recent call last)

 

<ipython-input-8-05c1c4b07ca6> in <module>

      1 # But don't mistake them for kwargs

----> 2 pep570_func(10, bar=1)

 

 

TypeError: pep570_func() got some positional-only arguments passed as keyword arguments: 'bar'

For more details check out the PEP: PEP-570

 

 

Tags: