Coding Python in VS Code (vs Spyder)

There are a lot of different Python Integrated Development Environments (IDE). This article will discuss using VS Code, a free open-source offering from Microsoft vs Spyder, another open-source offering.

Spyder is provided out of the box with the popular Anaconda Python distribution. Anaconda generally targets those working in data science because it provides many common data science-based packages pre-installed. Spyder gives an interactive experience, showing the user both a .py file for coding alongside an IPython console for running sections of code at a time and seeing the results. The IPython console maintains a persistent state of used variables, allowing the developer to inspect Python objects as they go and run ad hoc code snippets. For example, they can print the value of a dictionary key or try basic mathematical operations. The persistent state also provides for Spyder to show the developer a variable explorer. The variable explorer is convenient for comprehending what variables are defined and their respective values as you iteratively work through the Python code. With these features, it is not hard to see why beginning Python developers like using Spyder. Any script of moderate complexity is bound to require a lot of trial and error, and Spyder makes that feedback loop very short.

I'm going to make a case though, that aspects of Spyder and these same conveniences, make Spyder less ideal for general Python development. Then describe how to leverage VS Code, an extensible and general-purpose IDE, for Python coding.

Spyder

If you are a data scientist, trained in Python, using Spyder makes a lot of sense. Especially if you are using it from the Anaconda distribution. Almost everything you might need for data transformations, analysis, charting, to training machine learning models is already installed for you. You can iteratively update a matplotlib chart, adding more detail or adjusting the data, without having to re-run your entire script from the start each time. So, what are the downsides?

Spyder itself is written in Python, which means somewhere you need a version of Python installed to run it. What if you need to work with multiple versions of Python? Getting Spyder to use another version of Python other than the one it was installed with is a complicated exercise. By default, only the packages installed in the same Python installation are usable in your scripts. Again, not a huge deal if you are using Anaconda because they bundle everything with it.

For running general purpose scripting tasks, like scrapping a website or downloading data from an API, you don't need all those packages and you certainly don't need to require anyone else or your production system to install all those Spyder dependencies. That's a big reason using Python virtual environments has become a standard practice amongst developers. However, Spyder does not really have support for virtual environments. It is possible to use them, but you have to change a number of settings inside Spyder and restart it each time you switch environments as well as install other packages like IPython kernels which are used by Spyder but not by your script. Or you have to install Spyder into each of your virtual environments (which also still installs all those other dependencies for Spyder), and then you have multiple Spyder installations to contend with.

Spyder's variable explorer is super convenient, but I would also argue it can promote buggy and poor structured code. Recall, the variable explorer keeps track of the state of each variable in the current IPython console. Spyder supports Jupyter notebook like conventions to run sections of code at a time. A novice developer can then end up running multiple sections of their code non-linearly. For small scripts, it is unlikely to cause issues. But as the script grows in length and complexity, they can lose track of how the script will eventually run in production. For example, they might run a section of code that adds a value to a dictionary mid-way through the script. Then in an unrelated function at the beginning, make use of that new value. In production, when the script runs beginning to end, this could result in an error. My point is that the iterative nature of the IPython console, can encourage hard-to-read and buggy code.

VS Code

Now let's discuss some of the benefits to using VS Code instead. (VS Code is a personal preference. I'm not arguing that it is the best IDE for Python. Any of these points below can just as easily be made for many other IDEs. The intent is simply to contrast the development experience with Spyder specifically.)

VS Code does not come with support for Python OOB, but it has a robust ecosystem for extensions, and the Python extension is very good. It just takes a simple click to install it and you are good to go.

[File: 60c84317-76cd-40bb-8830-c83354559948]

Click on the left option for extensions marketplace, and search for Python extension from Microsoft.

Unlike Spyder, VS Code is not a Python application, so it does not rely on running inside a Python interpreter to function. This makes it agnostic to the version of Python you are using. In fact, you can have multiple versions of Python installed and easily swap which interpreter you are using with a click (no restart required). This also means that VS Code plays very well with virtual environments, since virtual environments behave essentially as self-contained Python installations. If you have multiple projects that use different environments, VS Code will remember which environment you are using for each project.

[File: c9d46804-e2fb-4afb-8185-17efc17a0d46]

Clicking on the active interpreter on the bottom, brings up a list of other known interpreters. You can also manually select another interpreter if it is not listed.

VS Code's Python extension does not come with a variable explorer like Spyder's. There is a separate extension that you can install to effectively run scripts in a similar notebook-like experience that Spyder provides. This also relies on the IPython kernels and other packages that Spyder also shares. If I wasn't clear before, I argue that this helping hand ultimately promotes poor coding practices for non-data science activities. But there is another way to get insights into how your code runs and be able to see what your variables look like at different points in your code.

All you have to do is set breakpoints and run the script with the Python debugger option. Setting a breakpoint means when the debugger runs, it will execute your script up until it reaches the breakpoint, then it will halt execution until you instruct it to continue.

[File: e35b77a4-668b-4a73-8324-087a169ba0b4]

Hover your cursor next to the line numbers, then click on the red dot that appears to set a breakpoint. Click it again to unset it. You can have multiple breakpoints set.

[File: 8fcce72c-38ad-43cd-8bb7-d1879e8903c4]

Click the option to run the Python Debugger. You can also use the shortcut key F5 instead. Note the active breakpoint indicated by the red dot.

While the code is halted, VS Code's Python extension will show the state of your variables. They can be browsed within the debug's variables pane. You can also hover your mouse over a variable and a tooltip will show with the current value. In the watch pane, you can add arbitrary Python expressions and see how the values change as you advance the code execution.

[File: 43a3373b-47b5-439e-aa8d-ceb7d45e9e3f]

Debugging a Python script in VS Code. The debug controls appear at the top while the debugger is running.

This experience does not provide the tight feedback loop experience from iteratively running your code, but it does ensure that you will understand how your code behaves when run in production. This minor compromise in convenience will naturally encourage you to structure your code in a way that is easy to read and maintain.


You'll only receive email when they publish something new.

More from Matt Carter
All posts