DEV Community

Bhuvaneswari Shanker
Bhuvaneswari Shanker

Posted on

Learn Python from JS/TS

This post is designed to help developers familiar with TypeScript/JavaScript transition to Python (v3.10).

Table of Contents

  1. Variables
  2. Data Types
  3. Functions
  4. Control Flow
  5. Loops
  6. Classes & OOP
  7. Inheritance
  8. Modules / Imports
  9. Exception Handling
  10. Async / Await
  11. Spread & Rest Operators
  12. Object Destructuring / Sequence Unpacking
  13. Interfaces
  14. Hoisting & Scopes
  15. Closures
  16. Coroutines
  17. Futures & Concurrency
  18. Decorators
  19. Special Methods / Dunder Methods
  20. 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;
Enter fullscreen mode Exit fullscreen mode

Python

x: int = 5
y: str = "hello"
z = True
Enter fullscreen mode Exit fullscreen mode

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};
Enter fullscreen mode Exit fullscreen mode

Python Example:

arr: list[int] = [1, 2, 3]
tup: tuple[str, int] = ("a", 1)
obj: dict[str, int] = {"name": "Alice", "age": 25}
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

Python

def add(a: int, b: int) -> int: return a + b

add = lambda a, b: a + b
Enter fullscreen mode Exit fullscreen mode
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"); 
}
Enter fullscreen mode Exit fullscreen mode

Python

if x > 5:
    print("yes")
else:
    print("no")
Enter fullscreen mode Exit fullscreen mode

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);
});
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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(){...}
Enter fullscreen mode Exit fullscreen mode

Python

from os import read

Enter fullscreen mode Exit fullscreen mode

8. Exception Handling

ts -> try, catch, finally
py -> try, except, finally

Typescript Example

try {
    riskyOperation();
} catch (err) {
    console.error(err);
} finally {
    cleanup();
}
Enter fullscreen mode Exit fullscreen mode

Python Example

try:
    risky_operation()
except Exception as err:
    print(err)
finally:
    cleanup()
Enter fullscreen mode Exit fullscreen mode

9. Async/Await

typescript

async function fetchData() { await fetch(url); }

Enter fullscreen mode Exit fullscreen mode

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()

Enter fullscreen mode Exit fullscreen mode

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});
Enter fullscreen mode Exit fullscreen mode

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)

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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"))

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode
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())
Enter fullscreen mode Exit fullscreen mode

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())
Enter fullscreen mode Exit fullscreen mode

Output

A 0
B 0
A 1
B 1
A 2
B 2
Enter fullscreen mode Exit fullscreen mode

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())

Enter fullscreen mode Exit fullscreen mode

output:

done
Enter fullscreen mode Exit fullscreen mode

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.

  1. Tasks may interleave on a single thread.
  2. 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]

Enter fullscreen mode Exit fullscreen mode

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]

Enter fullscreen mode Exit fullscreen mode

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())

Enter fullscreen mode Exit fullscreen mode
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


Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
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

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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)

Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)