<jupyter_start><jupyter_text>What’s new in Python 3.8?In Python 3.8, the syntax is simplified and support for C libraries is also improved. Below is a brief overview of some of the new features. You can get a complete overview in [What’s New In Python 3.8](https://docs.python.org/3/whatsnew/3.8.html).  Installation Check<jupyter_code>!python3 -V<jupyter_output>Python 3.8.0<jupyter_text>or<jupyter_code>import sys
assert sys.version_info[:2] >= (3, 8)<jupyter_output><empty_output><jupyter_text>Assignment Expressions: Walrus operator `:=`So far, e.g. `env_base` can be determined by pip as follows:<jupyter_code>import os
def _getuserbase():
    env_base = os.environ.get("PYTHONUSERBASE", None)
    if env_base:
        return env_base<jupyter_output><empty_output><jupyter_text>This can now be simplified with:<jupyter_code>def _getuserbase():
    if env_base := os.environ.get("PYTHONUSERBASE", None):
        return env_base<jupyter_output><empty_output><jupyter_text>Multiple nested `if`, such as in [cpython/Lib/copy.py](https://github.com/python/cpython/blob/main/Lib/copy.py), can also be avoided. This<jupyter_code>from copyreg import dispatch_table
def copy(x):
    cls = type(x)
    reductor = dispatch_table.get(cls)
    if reductor:
        rv = reductor(x)
    else:
        reductor = getattr(x, "__reduce_ex__", None)
        if reductor:
            rv = reductor(4)
        else:
            reductor = getattr(x, "__reduce__", None)
            if reductor:
                rv = reductor()
            else:
                raise Error(
                    "un(deep)copyable object of type %s" % cls)<jupyter_output><empty_output><jupyter_text>becomes that:<jupyter_code>def copy(x):
    cls = type(x)
    reductor = dispatch_table.get(cls)
    if reductor := dispatch_table.get(cls):
        rv = reductor(x)
    elif reductor := getattr(x, "__reduce_ex__", None):
        rv = reductor(4)
    elif reductor := getattr(x, "__reduce__", None):
        rv = reductor()
    else:
        raise Error("un(deep)copyable object of type %s" % cls)<jupyter_output><empty_output><jupyter_text>*Positional-only* parametersIn Python 3.8 a function parameter can be specified position-related with `/`. Several Python functions implemented in C do not allow keyword arguments. This behavior can now be emulated in Python itself, e.g. for the [pow()](https://docs.python.org/3/library/functions.htmlpow) function:<jupyter_code>def pow(x, y, z=None, /):
    "Emulate the built in pow() function"
    r = x ** y
    return r if z is None else r%z<jupyter_output><empty_output><jupyter_text>`f-strings` support `=` for self-documenting expressions and debugging<jupyter_code>user = 'veit'
member_since = date(2012, 1, 30)
f'{user=} {member_since=}'<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11813285457809695, 'fraction_numerical': 0.010053859964093357, 'mean_word_length': 3.862129144851658, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 33, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '255149', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 957, 'n_tokens_neox': 944, 'n_words': 240, 'path': 'docs/workspace/jupyter/kernels/python38.ipynb', 'repo_name': 'veit/jupyter-tutorial', 'size': '2785'}