New Features in Python 3.8
Tags: python
Published: 2020-03-14 19:33:41

Not a long time ago new Python 3.8 has arrived. It brought two very useful features and one syntax construction which will definitely appear in the future libraries.

## Better f-strings

The amazing python f-string became even better. **f-string** was introduced in  Python 3.6 and it is the best string formatting approach which I've ever seen. 

The syntax is simple. For example, you have a variable `name` and would like to print it - you can write `print(f'Hello {name}')` and that all. No need to call any additional functions (such as format()). Basically, you can use any variable available in current scope. Moreover, you can extract elements from the dict or list by using already known syntax `print('Hello {person["name"]}')`.

In Python 3.8 it becomes much easier to use f-strings for debugging. Now, you can also do the following: `print(f'{name=}')` will output `name=Andrew`. It just adds name of the variable and its value. Moreover, you still can use f-string formatting:

```python
    >>> from math import pi
    >>> print(f'{pi=:.3f}')
    pi=3.142
    >>> print(f'{pi=:.5f}')
    pi=3.14159
```

## New assignment expression

From time to time everybody faces the case when you need call a function in the if-condition and then use the value it returns if  the condition is true. Most of the time the code looks like this:

```python
    valid_elements = get_valid_elements(elements)
    if len(valid_elements):
        process(valid_elements)
```

Python 3.8 has a new syntactic sugar to simplify it and make it even more readable. The new operator is known as "the walrus operator". It assigns computed value to the variable and simultaneously returns it as it was a function call. So, we can to rewrite the code above as follows:

```python
    if len(valid_elements := get_valid_elements(elements)):
        process(valid_elements)
```

It is also very useful in the `while` loops as now there is no need to make a first function call before the loop.

```python
    while user_input := input()):
        process(user_input)

    # instead of
    user_input = input()
    while user_input:
        process(user_input)
        user_input = input()
```

## New syntax for position-only arguments

The next feature isn't so applicable in daily programming but it will be definitely used in libraries. The libraries developers always tries to protect user from misuse of the functions and their parameters. As Python is dynamically-typed language it becomes quite simple to pass wrong value to the wrong parameters. There exists a few techniques to help user not to save user from doing so, such as named parameters (e.g. `unlock(key="42")`). The new one is also serves the purpose of protecting user from misuse of the function's parameters. 

```python
    def f(a, b, /, c, d, *, e, f):
        print(a, b, c, d, e, f)
```

The `/` means that all the preceding parameters (a and b) should be positional only. The `*` means that all the following parameters (e and f) should be keywords only. So, be ready to see it in the code😀.

```python
    >>> f(1, 2, 3, 4, 5, f=6) # is invalid as 'e' should have keyword
    >>> f(1, b=2, c=3, d=4, e=5, f=6) # is also invalid as 'b' should be without keyword
    >>> f(1, 2, 3, d=4, e=5, f=6) # is valid
```

There a lot more changes in the Python 3.8 you can find the complete list in the [official article](https://docs.python.org/3/whatsnew/3.8.html).