To run Python on a Mac properly, install your own interpreter with Homebrew or pyenv instead of relying on the system Python, then run your scripts with the python3 command inside a per-project virtual environment. Learning how to run Python on Mac is mostly about avoiding one trap: the Python that comes with macOS is there for the operating system, not for you. This guide walks from a clean machine to running your first script the way a working developer actually does it.
Why not just use the built-in Python
macOS includes a Python interpreter, and you can technically run scripts with it. You should not build on it. It exists to support macOS's own tooling, Apple controls its version and can change or remove it in an OS update, and messing with its packages can break system utilities that depend on it. On top of that, it tends to lag behind current Python releases. The clean approach is to install a separate interpreter you own and control, and leave the system copy alone.
Before installing anything, check what you already have:
python3 --version
which python3
If that points into /usr/bin, you are looking at the system Python and it is time to install your own.
Installing Python with Homebrew
Homebrew is the standard macOS package manager and the simplest path for most people. If you do not have it, install it from brew.sh, then install Python:
brew install python
Homebrew places its Python ahead of the system one on your PATH and gives you both python3 and pip3. Confirm it worked and that you are now using the Homebrew copy:
python3 --version
which python3 # should point under /opt/homebrew or /usr/local, not /usr/bin
On Apple Silicon Macs Homebrew lives under /opt/homebrew; on older Intel Macs it is /usr/local. Either way, the point is that which python3 no longer shows /usr/bin.
Installing Python with pyenv for multiple versions
If you work on projects that need different Python versions, pyenv is the better tool because it lets you install and switch between many versions cleanly:
brew install pyenv
pyenv install 3.12.4
pyenv global 3.12.4
pyenv works by inserting shims on your PATH, so add its initialization to your shell profile (~/.zshrc on modern macOS, which uses zsh by default) as the pyenv install output instructs, then restart your terminal. After that, pyenv local 3.11.9 inside a project directory pins that project to a specific version without affecting anything else. This is the setup most professional Python developers on macOS end up with.
Running a Python script and the REPL
With a real interpreter installed, running code is straightforward. Create a file:
# hello.py
print("Running Python on macOS")
Then run it from the terminal, which is what people mean when they ask how to run a Python script on Mac:
python3 hello.py
For quick experiments, launch the interactive interpreter (the REPL) by running python3 with no arguments; you type expressions and see results immediately, and exit() leaves it. You can also make a script directly executable by adding a shebang line, #!/usr/bin/env python3, as the first line, running chmod +x hello.py, and then invoking it as ./hello.py. And you do not strictly need the terminal at all: editors like VS Code with the Python extension give you a run button, though knowing the command-line way pays off when you deploy.
Isolate every project with a virtual environment
This is the habit that separates a smooth Python setup from a painful one. A virtual environment is a self-contained copy of Python and its installed packages scoped to a single project, so Project A's dependencies never collide with Project B's, and you never pollute your global interpreter. Python ships this built in:
cd my-project
python3 -m venv .venv
source .venv/bin/activate
Your prompt now shows (.venv), and any pip install goes into that environment only. Install a package and freeze your dependencies so the project is reproducible:
pip install requests
pip freeze > requirements.txt
When you are done, deactivate returns you to the base shell. Anyone who clones your project can recreate the exact environment with python3 -m venv .venv, activate it, and run pip install -r requirements.txt. Never run sudo pip install to work around a permissions error, because that writes into a shared interpreter and is exactly the kind of change that breaks things later.
A note on dependency safety
Once you are installing packages with pip, you are pulling code from PyPI into your project, and that is worth a moment of care. Pin your dependencies with a requirements.txt (or a lockfile from a tool like Poetry or uv) so an install today produces the same versions as an install next month. Be deliberate about what you add, since a single package can drag in a long chain of transitive dependencies, each of which is code you are trusting. Periodically check your dependencies for known vulnerabilities; an SCA tool such as Safeguard can scan a requirements.txt and flag packages with disclosed CVEs. Our SCA product overview covers how that works, and the Safeguard Academy has a primer on Python dependency hygiene.
FAQ
Should I use the Python that comes with macOS?
No. The built-in Python exists to support the operating system, is controlled by Apple, and can change or break with OS updates. Install your own interpreter with Homebrew or pyenv and leave the system copy alone.
What is the difference between python and python3 on a Mac?
On modern macOS the python3 command is the one you want; a bare python command may be missing or point somewhere unexpected. After installing your own interpreter via Homebrew or pyenv, python3 resolves to it. Inside an activated virtual environment, python also points at the right interpreter.
How do I run a Python script on Mac?
Open Terminal, navigate to the folder containing your script, and run python3 yourscript.py. For quick experiments, run python3 alone to get an interactive REPL. You can also add a shebang line and make the file executable to run it as ./yourscript.py.
Do I really need a virtual environment for every project?
For anything beyond a throwaway one-liner, yes. A virtual environment keeps each project's dependencies isolated so they never collide and never pollute your global interpreter. It also makes your project reproducible for anyone else who clones it.