This content originally appeared on DEV Community and was authored by Bhuvaneswari Shanker
This post is designed to help developers familiar with TypeScript/JavaScript transition to Python (v3.10).
Table of Contents
- Variables
- Data Types
- Functions
- Control Flow
- Loops
- Classes & OOP
- Inheritance
- Modules / Imports
- Exception Handling
- Async / Await
- Spread & Rest Operators
- Object Destructuring / Sequence Unpacking
- Interfaces
- Hoisting & Scopes
- Closures
- Coroutines
- Futures & Concurrency
- Decorators
- Special Methods / Dunder Methods
- Iterators & Generators
Cheat sheet - Frequently used helper methods
1. Variables
Python doesn’t require let/const/var. Types are optional in python.
TypeScript
let x: number = 5;
const y = "hello";
var z = true;
Python
x: int = 5
y: str = "hello"
z = True
2. Data types
TypeScript | Python |
---|---|
number |
int , float
|
string |
str |
boolean |
bool |
any |
Any (from typing ) |
array: number[] |
list[int] |
tuple: [string, number] |
tuple[str, int] |
object |
dict |
Typescript Example:
let arr: number[] = [1, 2, 3];
let tup: [string, number] = ["a", 1];
let obj: {name: string, age: number} = {name: "Alice", age: 25};
Python Example:
arr: list[int] = [1, 2, 3]
tup: tuple[str, int] = ("a", 1)
obj: dict[str, int] = {"name": "Alice", "age": 25}
Object Type | Mutable? | Behavior when passed to function |
---|---|---|
list , dict
|
✅ | Passed by reference → changes affect original |
Custom objects | ✅ | Passed by reference → changes affect original |
int , float
|
❌ | Passed by value → cannot mutate original |
str , tuple
|
❌ | Passed by value → cannot mutate original |
3. Functions
Typescript
function add(a: number, b: number): number { return a + b; }
(a,b) => a+b // Arrow functions
Python
def add(a: int, b: int) -> int: return a + b
add = lambda a, b: a + b
Feature | JS Arrow Function | Python Lambda |
---|---|---|
Syntax | (a, b) => a + b |
lambda a, b: a + b |
Anonymous | Yes | Yes |
Implicit return | ✅ (expression only) | ✅ (expression only) |
Multiple statements | ❌ (unless wrapped in {} ) |
❌ (expression only) |
this binding |
Lexical (inherits outer this) | ❌ Not applicable; uses self in methods |
Scope | Block scope | Uses normal Python scoping rules |
4. Control Flow
No braces {}, indentation defines blocks.
Typescript
if (x > 5) { console.log("yes");
} else {
console.log("no");
}
Python
if x > 5:
print("yes")
else:
print("no")
5. Loops
No parentheses or braces or semicolon, indentation defines the block.
Python uses range(n) for 0…n-1.
Python doesn’t have a forEach method for lists; a normal for loop is used.
TypeScript
for (let i = 0; i < 5; i++) {
console.log(i);
}
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
const arr = [10, 20, 30];
arr.forEach((num) => {
console.log(num);
});
Python
for i in range(5):
print(i)
//or
arr = [10, 20, 30]
for num in arr:
print(num)
i = 0
while i < 5:
print(i)
i += 1
for index, value in enumerate(arr):
print(index, value)
6. Classes & OOP
this(ts/js) → self(py)
No public/private keywords; use _name for private convention.
Python doesn't need 'new' keyword to create objects for a class.
Unlike TS, Python lets you add attributes dynamically to objects
Typescript class
class Person {
name: string;
constructor(name: string) { this.name = name; }
greet() { console.log("Hello " + this.name); }
}
const p1 = new Person("Alice");
console.log(p1.name); // Output: Alice
p1.greet(); // Hello Alice
Python class
class Person:
def __init__(self, name: str):
self.name = name
def greet(self):
print("Hello " + self.name)
p1 = Person("Alice")
print(p1.name) # Output: Alice
p1.greet() # Hello Alice
# Unlike TS, Python lets you add attributes dynamically to objects:
p1.age = 25
print(p1.age) # 25
Inheritance
TypeScript class Child extends Parent {}
Python class Child(ParentClassName)
TypeScript super()
Python super().__init__()
TypeScript allows only single class inheritance, multi-level inheritance, doesn't support multiple inheritance by default but can be implemented using interfaces and mixins.
Python allows all types of inheritance, including multiple and hybrid inheritance.
Python resolves method conflicts using MRO (Method Resolution Order), which is left-to-right (class C(A, B) → A before B).
Typescript Example for inheritance
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak() {
console.log(this.name + " makes a sound");
}
}
class Dog extends Animal {
constructor(name: string) {
super(name); // Call parent constructor
}
speak() {
console.log(this.name + " barks");
}
}
const d = new Dog("Buddy");
d.speak(); // Buddy barks
Python example for inheritance
class Animal:
def __init__(self, name: str):
self.name = name
def speak(self):
print(self.name + " makes a sound")
class Dog(Animal):
def __init__(self, name: str):
super().__init__(name) # Call parent constructor
def speak(self):
print(self.name + " barks")
d = Dog("Buddy")
d.speak() # Buddy barks
7. Modules / Imports
TS/JS → Must export explicitly.
Python → Everything is importable by default (unless private name or restricted by `all).
all_ = ["Person"] # only Person is exportable from this file.py`
Typescript
import { readFile } from 'fs';
export function something(){...}
Python
from os import read
8. Exception Handling
ts -> try, catch, finally
py -> try, except, finally
Typescript Example
try {
riskyOperation();
} catch (err) {
console.error(err);
} finally {
cleanup();
}
Python Example
try:
risky_operation()
except Exception as err:
print(err)
finally:
cleanup()
9. Async/Await
typescript
async function fetchData() { await fetch(url); }
python
import asyncio, aiohttp
async def fetch_data():
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
return await resp.text()
10. Spread & Rest Operators - Unpacking & Variadic Operators
JS/TS ...spread → Python * (for lists/tuples) and ** (for dicts).
JS/TS ...rest in functions → Python *args (positional) and **kwargs (keyword args).
Typescript examples
const arr1 = [1, 2, 3];
const arr2 = [0, ...arr1, 4];
console.log(arr2); // [0, 1, 2, 3, 4]
const obj1 = {a: 1, b: 2};
const obj2 = {...obj1, c: 3};
console.log(obj2); // {a: 1, b: 2, c: 3}
function sum(...nums: number[]): number {
return nums.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
function printUser({name, age}: {name: string; age: number}) {
console.log(name, age);
}
printUser({name: "Alice", age: 25});
Python Examples
arr1 = [1, 2, 3]
arr2 = [0, *arr1, 4]
print(arr2) # [0, 1, 2, 3, 4]
obj1 = {"a": 1, "b": 2}
obj2 = {**obj1, "c": 3}
print(obj2) # {'a': 1, 'b': 2, 'c': 3}
def sum_all(*nums: int) -> int:
return sum(nums)
print(sum_all(1, 2, 3, 4)) # 10
def print_user(**kwargs):
print(kwargs["name"], kwargs["age"])
print_user(name="Alice", age=25)
11. No object destructuring, only sequence unpacking.
Python examples
a, b, c = 1, 2, 3
print(a, b, c) # 1 2 3
a, *rest = [1, 2, 3, 4, 5]
print(a) # 1
print(rest) # [2, 3, 4, 5]
user = {"name": "Alice", "age": 25}
name, age = user["name"], user["age"]
print(name, age) # Alice 25
12. No interfaces in python
Python has no explicit interface keyword.
Use Abstract Base Classes (ABC) or Protocols if you want strict contracts.
Python mostly relies on duck typing → “if it walks like a duck and quacks like a duck, it’s a duck.”
Example:
# 1. ABC
from abc import ABC, abstractmethod
class Person(ABC):
@abstractmethod
def greet(self):
pass
class Student(Person):
def __init__(self, name: str):
self.name = name
def greet(self):
print("Hello " + self.name)
#Protocols
from typing import Protocol
class Greeter(Protocol):
name: str
def greet(self) -> None: ...
class Student:
def __init__(self, name: str):
self.name = name
def greet(self) -> None:
print("Hello " + self.name)
def welcome(g: Greeter):
g.greet()
welcome(Student("Alice"))
#Duck typing
class Student:
def __init__(self, name):
self.name = name
def greet(self):
print("Hello " + self.name)
def welcome(person):
person.greet() # no interface needed!
welcome(Student("Alice"))
13. No hoisting, uses function/global/nonlocal scopes
Hoisting → Not in Python.
Block scope → Not in Python (if/for/while don’t create scopes).
Function scope → Yes, like JS.
Global scope → Yes, but must declare global to modify.
Nonlocal → Python-only (for nested functions).
Examples:
print(a) # NameError - no hoisting
a = 5
if True:
x = 10
print(x) # 10 (still accessible, variables leaks out from if,while,for)
def foo():
x = 10
print(x)
foo()
print(x) # NameError x is function scoped
x = 5
def foo():
global x
x = 10
foo()
print(x) # 10
def outer():
x = "outer"
def inner():
nonlocal x
x = "inner"
inner()
print(x)
outer() # inner
Feature | JS / TS Closures | Python Closures |
---|---|---|
Captures outer variables | ✅ | ✅ |
Modify outer variables | ✅ directly | ✅ need nonlocal
|
Syntax |
function or arrow functions |
def functions |
Lexical scope | ✅ | ✅ |
16. Coroutines
A coroutine is like a function that can pause and resume.
Example:
import asyncio
async def fetch_data():
print("start")
await asyncio.sleep(1) # pauses here, gives control back to event loop
print("end")
asyncio.run(fetch_data())
async def → defines a coroutine.
await → suspends coroutine until the awaited task is done.
The event loop runs coroutines, switching between them when they pause.
Multitasking example
import asyncio
async def task(name):
for i in range(3):
print(f"{name} {i}")
await asyncio.sleep(0.5)
async def main():
await asyncio.gather(task("A"), task("B"))
asyncio.run(main())
Output
A 0
B 0
A 1
B 1
A 2
B 2
15. Futures in Python
A Future represents a placeholder for a result that is not yet available — like a JS Promise.
Used in asyncio and concurrent.futures.
Lets you schedule work and get the result later.
Example:
import asyncio
async def task():
await asyncio.sleep(1)
return "done"
async def main():
future = asyncio.create_task(task()) # returns a Future
result = await future # wait for completion
print(result)
asyncio.run(main())
output:
done
16. JS Event loop vs Python asyncio Event loop
Feature | JavaScript Event Loop | Python asyncio Event Loop |
---|---|---|
Threads | Single-threaded (libuv) | Single-threaded (unless threads/multiprocessing) |
Microtasks | Yes (Promises run before timers) | No explicit microtask queue |
Async Syntax |
async/await built on Promises |
async/await built on coroutines |
Scheduling | Microtasks, macrotasks, timers, I/O | Tasks, Futures, coroutines, callbacks |
Parallel CPU work | Worker threads / child_process | Multiprocessing (bypasses GIL) |
17. Concurrency in Python
Concurrency = handling multiple tasks at the same time, but not necessarily in parallel.
- Tasks may interleave on a single thread.
- Parallelism = tasks truly run at the same time (requires multiple CPU cores).
1. Threading
Uses threading.Thread.
Multiple threads share memory.
GIL limits CPU-bound parallelism, but threads are great for I/O-bound tasks.
import threading
import time
def worker(n):
time.sleep(1)
print(f"Worker {n} done")
threads = [threading.Thread(target=worker, args=(i,)) for i in range(3)]
[t.start() for t in threads]
[t.join() for t in threads]
2. Process
Uses multiprocessing.Process.
Each process has its own memory → bypasses GIL.
Ideal for CPU-heavy tasks.
from multiprocessing import Process
def worker(n):
print(f"Worker {n} done")
processes = [Process(target=worker, args=(i,)) for i in range(3)]
[p.start() for p in processes]
[p.join() for p in processes]
3. asyncio
Single-threaded, event-loop-driven.
Use async def + await + asyncio.run()
Efficient for network requests, file I/O, or any wait-based operations.
import asyncio
async def task(n):
await asyncio.sleep(1)
print(f"Task {n} done")
async def main():
await asyncio.gather(*(task(i) for i in range(3)))
asyncio.run(main())
Model | Thread | Process | Asyncio |
---|---|---|---|
Use case | I/O | CPU | I/O |
True parallelism | ❌ GIL limits CPU | ✅ separate memory | ❌ single-threaded |
Syntax | threading.Thread | multiprocessing.Process | async/await |
Shared memory | ✅ | ❌ | ✅ |
GIL = Global Interpreter Lock
It’s a mutex (lock) in CPython (the standard Python interpreter).
Purpose: Ensure that only one thread executes Python bytecode at a time.
How GIL Works Internally
Every CPython interpreter has a single global lock (the GIL).
When a thread wants to execute Python code:
It acquires the GIL.
Executes some bytecode instructions.
Releases the GIL (or periodically checks if another thread should run).
CPython switches threads periodically, typically every 5 milliseconds (or after PyEval_Threadslice ticks).
C extensions can temporarily release the GIL if they perform long-running C operations, allowing other threads to run.
I/O-bound tasks
→ GIL is released when threads wait on I/O, allowing other threads to run.
CPU-bound tasks
→ threads compete for GIL → no real speedup on multiple cores.
IPC
Feature | Threads | Processes |
---|---|---|
Memory shared | ✅ Yes | ❌ No |
Communication channel | Optional (direct vars) | Required IPC (Queue, Pipe, SharedMemory) |
Race condition risk | ✅ Yes (use locks) | ✅ Minimal (processes isolated) |
Use case | I/O-bound concurrency | CPU-bound parallelism |
18. Decorators
A decorator is a function that wraps another function, method, or class, modifying its behavior without changing its code.
TS decorator Example
Must enable experimentalDecorators in tsconfig.json.
Can decorate classes, methods, properties, or parameters.
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${propertyKey} with`, args);
return original.apply(this, args);
}
}
class Example {
@log
greet(name: string) {
console.log("Hello " + name);
}
}
const ex = new Example();
ex.greet("Alice");
// Output:
// Calling greet with ['Alice']
// Hello Alice
Python decorators Example
Decorators can wrap functions, methods, or classes.
Use @decorator_name syntax.
def log(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with {args}")
return func(*args, **kwargs)
return wrapper
class Example:
@log
def greet(self, name):
print("Hello", name)
ex = Example()
ex.greet("Alice")
# Output:
# Calling greet with (<__main__.Example object at 0x...>, 'Alice')
# Hello Alice
Feature | TypeScript Decorator | Python Decorator |
---|---|---|
Syntax | @decorator |
@decorator |
Targets | Class, method, property, parameter | Function, method, class |
Arguments | target, propertyKey, descriptor | function (or class) |
Returns | descriptor / modified function | wrapped function or class |
Requires setup | experimentalDecorators: true |
Built-in |
Meta-programming power | Limited to TS metadata + reflection | Full access to function/class objects |
@property - Property decorator
Decorator that turns a method into a “readable attribute”
Allows custom behavior when getting, setting, or deleting an attribute
Lets you encapsulate logic without changing the external API
class Person:
def __init__(self, name):
self._name = name # convention: _name = private
@property
def name(self):
"""Getter for name"""
return self._name
@name.setter
def name(self, value):
"""Setter for name"""
if not value:
raise ValueError("Name cannot be empty")
self._name = value
p = Person("Alice")
print(p.name) # Alice (calls getter)
p.name = "Bob" # calls setter
print(p.name) # Bob
# p.name = "" # raises ValueError
19. Special method or dunner methods
Also called “dunder” methods (double underscore): method
Allow objects to behave like built-in types
Examples: string representation, comparison, arithmetic
Python Special Method | Purpose | TS Equivalent (approx) |
---|---|---|
__str__ |
Human-readable string | toString() |
__repr__ |
Debug string | Custom method / JSON.stringify |
__eq__ |
Equality operator |
== / custom method |
__add__ |
Addition operator | No direct equivalent |
Others |
__sub__ , __len__ , __getitem__
|
Methods / index access |
20. Iterators & Generators
Iterable
An object you can loop over with for
Must implement iter() method that returns an iterator
Iterator
An object that produces items one at a time
Must implement next() method (Python 3: next() function)
Raises StopIteration when done
# Iterable example
numbers = [1, 2, 3] # list is iterable
it = iter(numbers) # creates iterator
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
# next(it) -> StopIteration
Generator Functions
Functions that yield values one at a time using yield
Lazy evaluation → computes values on demand (memory efficient)
def count_up_to(n):
i = 1
while i <= n:
yield i
i += 1
for num in count_up_to(3):
print(num)
# Output: 1 2 3
List comprehension vs Generators
Feature | List Comprehension | Generator Expression |
---|---|---|
Syntax | [x*x for x in range(5)] |
(x*x for x in range(5)) |
Evaluation | Eager (creates full list) | Lazy (yields one item at a time) |
Memory Usage | High for large lists | Low (good for large datasets) |
Use Case | Small datasets / when all values are needed | Streaming / large datasets |
# List comprehension (eager)
squares_list = [x*x for x in range(5)]
print(squares_list) # [0, 1, 4, 9, 16]
# Generator expression (lazy)
squares_gen = (x*x for x in range(5))
for s in squares_gen:
print(s)
Summary
Iterable: object you can loop over (list, tuple, dict)
Iterator: produces items one at a time (next)
Generator function: uses yield, lazy evaluation, memory efficient
Generator expression: lazy, similar to list comprehension, uses parentheses
Helper Methods
1. String helper methods
Operation / Method | Python Example | TypeScript/JS Equivalent | Notes |
---|---|---|---|
Lowercase | "Hello".lower() |
"Hello".toLowerCase() |
Returns new string |
Uppercase | "Hello".upper() |
"Hello".toUpperCase() |
Returns new string |
Strip / Trim | " Hello ".strip() |
" Hello ".trim() |
Removes leading/trailing whitespace |
Left/Right Trim |
" Hello".lstrip() / "Hello ".rstrip()
|
" Hello".trimStart() / "Hello ".trimEnd()
|
Python distinguishes left/right |
Replace | "Hello".replace("H","J") |
"Hello".replace("H","J") |
Returns new string |
Split | "a,b,c".split(",") |
"a,b,c".split(",") |
Returns list/array |
Join | ",".join(["a","b","c"]) |
["a","b","c"].join(",") |
Concatenate with separator |
StartsWith | "Hello".startswith("He") |
"Hello".startsWith("He") |
Returns bool |
EndsWith | "Hello".endswith("lo") |
"Hello".endsWith("lo") |
Returns bool |
Contains / Includes | "Hello" in "Hello World" |
"Hello World".includes("Hello") |
Python uses in operator |
Find / Index | "Hello".find("l") |
"Hello".indexOf("l") |
Returns first index or -1 (find ) |
Count occurrences | "Hello".count("l") |
N/A | Returns number of matches |
Format / Interpolation | f"Hello {name}" |
`Hello ${name}` |
f-strings are equivalent to template literals |
2. Array helper methods
Operation / Method | Python Example | TypeScript/JS Equivalent | Notes |
---|---|---|---|
Length | len(arr) |
arr.length |
Built-in function |
IndexOf | arr.index(2) |
arr.indexOf(2) |
Raises ValueError if not found |
Slice | arr[1:3] |
arr.slice(1,3) |
Returns a new list/array |
Splice / Insert |
arr[1:1] = [10] or arr.insert(1, 10)
|
arr.splice(1,0,10) |
Insert at index |
Append / Push | arr.append(4) |
arr.push(4) |
Adds single item at end |
Extend / Concat | arr.extend([4,5]) |
arr.concat([4,5]) |
Add multiple items |
Remove by value | arr.remove(2) |
arr.splice(arr.indexOf(2),1) |
Removes first occurrence |
Pop | arr.pop() |
arr.pop() |
Remove last item |
Shift / Pop first element | arr.pop(0) |
arr.shift() |
Remove first element |
Unshift / Insert at start | arr.insert(0, x) |
arr.unshift(x) |
Insert at beginning |
Includes / Membership | 2 in arr |
arr.includes(2) |
Returns bool |
Reverse | arr.reverse() |
arr.reverse() |
In-place |
Sort | arr.sort() |
arr.sort() |
In-place |
List Comprehension / Map | [x*2 for x in arr] |
arr.map(x => x*2) |
Returns new list/array |
Filter | [x for x in arr if x>2] |
arr.filter(x => x>2) |
Returns new list/array |
Reduce | from functools import reduce; reduce(func, arr) |
arr.reduce(func) |
Aggregate / accumulate values |
Every | all(x % 2 == 0 for x in arr) |
arr.every(x => x % 2 === 0) |
Returns True if all elements satisfy condition |
Some | any(x % 2 == 0 for x in arr) |
arr.some(x => x % 2 === 0) |
Returns True if any element satisfies condition |
Find | next((x for x in arr if x>2), None) |
arr.find(x => x>2) |
Returns first match or None |
ForEach / Loop | for x in arr: ... |
arr.forEach(x => ...) |
Iteration |
3. Dictionary / Object helper methods
Operation / Method | Python Example | TypeScript/JS Equivalent | Notes |
---|---|---|---|
Get value | d.get("key") |
obj.key / obj["key"]
|
Returns None if key not found |
Set value | d["key"] = value |
obj.key = value |
Add/update key |
Keys | d.keys() |
Object.keys(obj) |
Returns iterable |
Values | d.values() |
Object.values(obj) |
Returns iterable |
Items | d.items() |
Object.entries(obj) |
Returns key/value pairs |
Pop | d.pop("key") |
delete obj.key |
Removes key |
This content originally appeared on DEV Community and was authored by Bhuvaneswari Shanker

Bhuvaneswari Shanker | Sciencx (2025-09-11T13:32:37+00:00) Learn Python from JS/TS. Retrieved from https://www.scien.cx/2025/09/11/learn-python-from-js-ts/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.