Rust for Python Developers: A Practical Introduction

The best thing to happen to programming since C. Here's how to read it, through Python you already know.

Rust feels alien until you see it as a stricter Python with real types and no garbage collector. The payoff is C-level speed with memory safety the compiler proves for you.

Variables and types

python
# Python
x = 5
x = "now a string"   # fine, types are dynamic
rust
// Rust
let x = 5;          // immutable by default
let mut y = 5;      // mutable
y = 6;
// x = "nope";      // compile error: mismatched types
let name: &str = "zugzwang";

Ownership — the big idea

In Python, values are shared freely. In Rust, a value has exactly one owner, and when the owner goes out of scope the value is dropped. This is what removes the need for a garbage collector.

rust
let a = String::from("hello");
let b = a;           // a is MOVED into b
// println!("{}", a); // error: a was moved

// borrow instead:
let a = String::from("hello");
let b = &a;          // b borrows a; both usable
println!("{} {}", a, b);
Rule of thumb: functions take &T (borrow) unless they need to own or mutate, in which case &mut T.

Error handling is explicit

rust
fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 { return Err("division by zero".into()); }
    Ok(a / b)
}

match divide(4.0, 2.0) {
    Ok(v) => println!("{v}"),
    Err(e) => println!("error: {e}"),
}

Why we reach for Rust

  • Performance-critical paths in Python services (call out via PyO3).
  • CLI tools that start instantly.
  • Anything touching files, networks or bytes at scale.
  • Safety guarantees that make refactoring fearless.

Start with the Rust Book, then port one small Python script. You'll fight the borrow checker for a week, then never want to go back.

Your move

Want us to build this for you?

We turn tutorials like these into production systems every day. Tell us what you need.

Start a project →