Try out Walrus Operator in Python 3.8

The first alpha of Python 3.8 was just released at February 3, 2019. With that comes a major new feature in the form of PEP 572, Assignment Expressions, implemented by the amazing Emily Morehouse, Python Core Developer and Founder, Director of Engineering at Cuttlesoft.

What’s a walrus operator?

Walrus-operator is another name for assignment expressions. I think the official PEP does an excellent job of explaining the semantics.

# From: https://www.python.org/dev/peps/pep-0572/#syntax-and-semantics

# Handle a matched regex
if (match := pattern.search(data)) is not None:
    # Do something with match

# A loop that can't be trivially rewritten using 2-arg iter()
while chunk := file.read(8192):
   process(chunk)

# Reuse a value that's expensive to compute
[y := f(x), y**2, y**3]

# Share a subexpression between a comprehension filter clause and its output
filtered_data = [y for x in data if (y := f(x)) is not None]

This new operator has gotten sparked some lively opinions and debates, this article will not focus on that part. As many other I’m excited to try this out and see how it could be used in my own code, and that is the focus of this piece.

To get started we need to install Python 3.8, to ease switching between version I use a tool called pyenv. Details on how to install pyenv can be found here.

$ brew update
$ brew install pyenv

Short version for macOS users

At this point run pyenv init and follow the instructions.

Now lets install the development-version of python 3.8 using pyenv and set our shell to use this version, pipenv is also an alternative which wraps pyenv. But first we need to install and link zlib, otherwise you’ll run into the following error.

$ pyenv install 3.8-dev

python-build: use openssl from homebrew
python-build: use readline from homebrew
Cloning https://github.com/python/cpython...
Installing Python-3.8-dev...
python-build: use readline from homebrew

BUILD FAILED (OS X 10.14.2 using python-build 20180424)

Inspect or clean up the working tree at /var/folders/bj/zvdqzwk110gcrvtbw17wv1c80000gn/T/python-build.20190207152040.86672
Results logged to /var/folders/bj/zvdqzwk110gcrvtbw17wv1c80000gn/T/python-build.20190207152040.86672.log

Last 10 log lines:
    return _bootstrap(
  File "/private/var/folders/bj/zvdqzwk110gcrvtbw17wv1c80000gn/T/python-build.20190207152040.86672/Python-3.8-dev/Lib/ensurepip/__init__.py", line 117, in _bootstrap
    return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
  File "/private/var/folders/bj/zvdqzwk110gcrvtbw17wv1c80000gn/T/python-build.20190207152040.86672/Python-3.8-dev/Lib/ensurepip/__init__.py", line 27, in _run_pip
    import pip._internal
  File "<frozen zipimport>", line 241, in load_module
  File "<frozen zipimport>", line 709, in _get_module_code
  File "<frozen zipimport>", line 570, in _get_data
zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1

Luckily for us this is quite easy to fix.

# Install zlib
brew install zlib

# Add zlib-variables to your shell.
tee -a ~/.profile <<<CONF
export PKG_CONFIG_PATH="/usr/local/opt/zlib/lib/pkgconfig"
export LDFLAGS="-L/usr/local/opt/zlib/lib"
export CPPFLAGS="-I/usr/local/opt/zlib/include"
CONF

# Restart your shell
trap $SHELL EXIT && exit

Fix the zlib related problems like this

At this point you can simply install python 3.8 using pyenv.

*Install the alpha with pyenv install 3.8-dev

Voila we can now use Python 3.8 by running pyenv shell 3.8-dev

Victor Stinner, Python Core Developer wrote a pull-request back in July showcasing how the walrus-operator could be used in the python standard library, it’s a great way to see how this new syntax can be used.

Let’s try to use it ourselves! I’m going to write a piece of code using pre-3.8 syntax and then the same code with walrus operators. I created some dummy data based on jsonplaceholder where I want to check if a property exists and then print it.

sample_data = [
    {"userId": 1, "id": 1, "title": "delectus aut autem", "completed": False},
    {"userId": 1, "id": 2, "title": "quis ut nam facilis", "completed": False},
    {"userId": 1, "id": 3, "title": "fugiat veniam minus", "completed": False},
    {"userId": 1, "id": 4, "title": "et porro tempora", "completed": True},
    {"userId": 1, "id": 4, "title": None, "completed": True},
]

print("With Python 3.8 Walrus Operator:") 
for entry in sample_data: 
    if title := entry.get("title"):
        print(f'Found title: "{title}"')

print("Without Walrus operator:")
for entry in sample_data:
    title = entry.get("title")
    if title:
        print(f'Found title: "{title}"')

$ python --version; python walrus.py
Python 3.8.0a1+
With Python 3.8 Walrus Operator:
Found title: "delectus aut autem"
Found title: "quis ut nam facilis"
Found title: "fugiat veniam minus"
Found title: "et porro tempora"
Without Walrus operator:
Found title: "delectus aut autem"
Found title: "quis ut nam facilis"
Found title: "fugiat veniam minus"
Found title: "et porro tempora"

There you have it, Python 3.8 alpha up and running with a working copy of the walrus operator. Now it’s time to experiment more with this and put it to good use! Check out the official PEP for more detailed examples and the release notes for details on what more new things you can find in the 3.8a1 release.

Thank you for reading !

#Python #Development #Webdev

Try out Walrus Operator in Python 3.8
1 Likes8.85 GEEK