Mental Model — คิดแบบ Python
การเปลี่ยนแปลงที่ใหญ่ที่สุด: compiler หายไปแล้ว
หัวข้อที่มีชื่อว่า “การเปลี่ยนแปลงที่ใหญ่ที่สุด: compiler หายไปแล้ว”ใน TypeScript compiler (tsc) คือด่านป้องกันด่านแรก จับ type ที่ไม่ตรงกันตั้งแต่ก่อนโค้ดได้รัน พอย้ายมา Python ด่านนั้นหายไป เหลือแค่ runtime — interpreter ไม่ตรวจ type ให้เลย
Python มี type hints ให้ใช้ (และคุณควรใช้) แต่เป็นแค่ hint ถ้าอยากให้บังคับจริงต้องพึ่ง tool แยกอย่าง mypy หรือ pyright
Mental model: TypeScript บอกว่า “พิสูจน์ก่อนว่าปลอดภัย แล้วค่อยรัน” ส่วน Python บอกว่า “รันเลย ถ้าส่ง type ผิดค่อยเจอ runtime error เอา”
Dynamic typing
หัวข้อที่มีชื่อว่า “Dynamic typing”ตัวแปรใน Python เป็นแค่ label ที่ชี้ไปยัง object ตัวไหนก็ได้ และ type ติดอยู่กับ object ไม่ได้ติดอยู่กับชื่อตัวแปร ต่างจาก TypeScript ที่ตัวแปรถือ type ของตัวเองมาตั้งแต่ตอน compile
// TypeScript: variable has a compile-time typelet count: number = 0;count = "five"; // Error: Type 'string' is not assignable to type 'number'
function double(n: number): number { return n * 2;}# Python: variable is just a labelcount = 0count = "five" # perfectly legal at runtime
def double(n: int) -> int: # hints are documentation only return n * 2
print(double(3)) # 6print(double("x")) # TypeError at RUNTIME, not beforeInterpreter และ REPL
หัวข้อที่มีชื่อว่า “Interpreter และ REPL”TypeScript ต้องคอมไพล์เป็น JavaScript ก่อนถึงจะรันได้ ส่วน Python รันผ่าน interpreter — สั่ง python3 ใส่ source file ตรง ๆ ได้เลย ตอน develop ไม่มีขั้นตอน build
# TypeScript workflow# tsc index.ts → compiles to index.js# node index.js → runs the compiled output# ts-node index.ts → shortcut for development# Python workflow# python3 script.py → runs directly, no compile step# python3 → opens the interactive REPL# python3 -c "print(1)" → run a one-liner inlineSignificant indentation — ไม่มี curly braces
หัวข้อที่มีชื่อว่า “Significant indentation — ไม่มี curly braces”ข้อนี้คือสิ่งที่ TypeScript developer สังเกตเห็นเป็นอย่างแรก เพราะ Python ใช้การย่อหน้า (4 spaces ตามข้อกำหนด) กำหนดขอบเขตของ block ไม่มี { } ให้ยึด และ colon (:) คือสิ่งที่เปิด block ใหม่เสมอ
// TypeScriptfunction classify(n: number): string { if (n > 0) { return "positive"; } else if (n < 0) { return "negative"; } else { return "zero"; }}# Python — indentation IS the blockdef classify(n: int) -> str: if n > 0: return "positive" elif n < 0: # note: elif, not else if return "negative" else: return "zero"
print(classify(5)) # positiveprint(classify(-3)) # negativeprint(classify(0)) # zeroย่อหน้าผิดเมื่อไหร่ก็เป็น syntax error ทันที โชคดีที่ editor สาย Python ส่วนใหญ่จัด indentation 4 spaces ให้อัตโนมัติอยู่แล้ว
One obvious way — โค้ดแบบ “Pythonic”
หัวข้อที่มีชื่อว่า “One obvious way — โค้ดแบบ “Pythonic””TypeScript ยืดหยุ่นมาก จะใช้ class, functional composition, prototype chain หรือ plain object สลับกันไปมาก็ได้ ส่วน Python เชียร์ให้เหลือทางเดียวที่เป็นธรรมชาติที่สุด และชุมชนเรียกสไตล์นั้นว่า Pythonic — โค้ดที่กระชับ อ่านง่าย และใช้ฟีเจอร์ของภาษาตรงตามที่ออกแบบมา
// TypeScript: multiple ways to filterconst evens1 = nums.filter(n => n % 2 === 0);const evens2 = nums.reduce((acc, n) => n % 2 === 0 ? [...acc, n] : acc, []);// Both work; TS community accepts both# Python: list comprehension is the Pythonic waynums = [1, 2, 3, 4, 5, 6]evens = [n for n in nums if n % 2 == 0]print(evens) # [2, 4, 6]
# Works but less Pythonic:# evens = list(filter(lambda n: n % 2 == 0, nums))Explicit self ใน methods
หัวข้อที่มีชื่อว่า “Explicit self ใน methods”method ของ class ใน TypeScript ได้ this มาโดยปริยาย ส่วนใน Python ต้องประกาศ parameter self เป็น argument ตัวแรกให้ชัดเจน — interpreter ใส่ค่าให้เองตอนคุณเรียก method แต่คนที่ต้องเขียนประกาศไว้คือคุณ
// TypeScript: implicit thisclass Counter { private count: number = 0;
increment(): void { this.count++; // 'this' is implicit }
value(): number { return this.count; }}# Python: explicit selfclass Counter: def __init__(self): # called on Counter() self.count = 0 # instance attribute
def increment(self): # self is the instance self.count += 1
def value(self) -> int: return self.count
c = Counter()c.increment()c.increment()print(c.value()) # 2# Mental model: types live on objects, not variablesx = 42print(type(x).__name__) # int
x = "hello"print(type(x).__name__) # str
# Significant indentationdef classify(n: int) -> str: if n > 0: return "positive" elif n < 0: return "negative" else: return "zero"
for num in [5, -3, 0]: print(f"{num} is {classify(num)}")
# Pythonic list comprehensionevens = [n for n in range(1, 11) if n % 2 == 0]print("Evens:", evens)
# Explicit selfclass Counter: def __init__(self): self.count = 0
def increment(self): self.count += 1
def value(self) -> int: return self.count
c = Counter()c.increment()c.increment()print("Counter:", c.value())Loading Python runtime (first run only)…