I "grew up" on Python, then wrote a whole bunch of Go for my job. Then this
past Autumn re-visited Python to implement a networked terminal based game[1].
With what I learned about Go and concurrency, I would say that currently in
Python, writing concurrent code is not very hard, and is as close to Go as
you can get without actually just writing Go.
Now, you may be saying "but Python has the GIL, how can concurrency be easy in
Python?" I'd say, you're definitely not wrong that the GIL is a problem, but
it's not much of a problem for concurrency.
This goes back to the heart of Rob Pike's classic talk, "Concurrency Is Not
Parallelism"[2]. To quote Wikipedia:
In computer science, concurrency is the decomposability property of a
program, algorithm, or problem into order-independent or partially-ordered
components or units.
In Python, you can pretty easily emulate the conceptual properties of
Goroutines and Go channels with Python threads and queues. The problem is that
doing this in Python won't net you the performance increases you get with Go.
And I believe that is an important distinction. There are plenty of cases where
you don't care so much about the performance benefits of parallelism, but you
want the conceptual and implementation benefits of concurrency.
In closing, concurrency in Python is pretty easy to work with, it just performs
very poorly.
[1] - https://github.com/lelandbatey/defuse_division
[2] - https://blog.golang.org/concurrency-is-not-parallelism