Types & Variables
C# is statically typed: every variable's type is fixed at compile time, and the compiler stops you before a mismatched assignment ever runs. Python is dynamically typed: a variable is just a name pointing at whatever value you last assigned it, and the type lives with the value, not the variable. This is the change that trips up C# developers more than any other — the safety net you're used to leaning on moves.
💡 The Bottom Line
In Python, the same variable name can hold an int on one line and a str on
the next — nothing stops you. Type-related bugs that C# catches at compile time surface in
Python only when that line actually runs. This makes tests and type hints (covered below)
far more important in Python than they are in C#.
Declaring a variable
int age = 30;
string name = "Ada";
double price = 19.99;
bool isActive = true;
var inferred = 42; // still statically int
age = 30
name = "Ada"
price = 19.99
is_active = True
inferred = 42 # dynamically int, but could
# be reassigned to anything
📋 Key differences
- No type keyword at all — not even
var. The name is bound directly to a value. - Booleans are capitalized:
True/False, nottrue/false. - Naming convention is
snake_case(is_active), notcamelCase(isActive). - C#'s
varstill means a single, fixed, compiler-known type — Python has no equivalent of that guarantee.
⚠️ Gotcha
This is completely legal Python, and will not raise any error until the last line runs:
value = 42
value = "now I'm a string"
value = value + 1 # TypeError, at runtime, not before
C# would refuse to compile the equivalent code. Python only complains when the offending line actually executes — which means a rarely-hit branch can hide a type bug for a long time.
Reference types you already know, with new names
C#'s primitive/reference type split maps roughly onto Python's built-in types, though Python has far fewer numeric types to choose between:
int,long,shortin C# → justintin Python (arbitrary precision, no overflow to worry about).float,double,decimalin C# → justfloatin Python (a double-precision float under the hood).string→str.bool→bool(values capitalized, as shown above).null→None.
🙋 There Are No Dumb Questions
Q: If Python has no compile-time type checking, is it just less safe than C#?
A: It shifts when type errors are caught, not whether they exist — from compile time to
runtime (or to test time, if you have good test coverage). Python also supports optional
type hints (def greet(name: str) -> str:) that tools like mypy
check statically, closing much of that gap voluntarily — but unlike C#, nothing enforces
those hints at runtime by default.
Checking a type at runtime
if (obj is int) { ... }
Console.WriteLine(obj.GetType());
if isinstance(obj, int): ...
print(type(obj))
🔧 Try It Yourself
Write a Python function that takes a parameter and, using isinstance(), prints a
different message depending on whether it received an int, a str, or
neither. Call it three times with different types. Notice there's no error at the call
site for passing "the wrong type" — the function just has to defensively check, something
the C# compiler would have done for you automatically with typed parameters.
✅ Quick Check
A Python function expects a number but is accidentally called with a string. When does Python typically catch this, compared to C#?
Next up: C#'s List<T>, arrays, and Dictionary<K,V> all have Python
equivalents — but the syntax and mutability rules differ enough to trip people up. That's
Collections.