ข้ามไปยังเนื้อหา

Mental Model — คิดแบบ Python

ใน TypeScript compiler (tsc) คือด่านป้องกันด่านแรก จับ type ที่ไม่ตรงกันตั้งแต่ก่อนโค้ดได้รัน พอย้ายมา Python ด่านนั้นหายไป เหลือแค่ runtime — interpreter ไม่ตรวจ type ให้เลย

Python มี type hints ให้ใช้ (และคุณควรใช้) แต่เป็นแค่ hint ถ้าอยากให้บังคับจริงต้องพึ่ง tool แยกอย่าง mypy หรือ pyright

Mental model: TypeScript บอกว่า “พิสูจน์ก่อนว่าปลอดภัย แล้วค่อยรัน” ส่วน Python บอกว่า “รันเลย ถ้าส่ง type ผิดค่อยเจอ runtime error เอา”

ตัวแปรใน Python เป็นแค่ label ที่ชี้ไปยัง object ตัวไหนก็ได้ และ type ติดอยู่กับ object ไม่ได้ติดอยู่กับชื่อตัวแปร ต่างจาก TypeScript ที่ตัวแปรถือ type ของตัวเองมาตั้งแต่ตอน compile

TypeScript
// TypeScript: variable has a compile-time type
let count: number = 0;
count = "five"; // Error: Type 'string' is not assignable to type 'number'
function double(n: number): number {
return n * 2;
}
Python
# Python: variable is just a label
count = 0
count = "five" # perfectly legal at runtime
def double(n: int) -> int: # hints are documentation only
return n * 2
print(double(3)) # 6
print(double("x")) # TypeError at RUNTIME, not before

TypeScript ต้องคอมไพล์เป็น JavaScript ก่อนถึงจะรันได้ ส่วน Python รันผ่าน interpreter — สั่ง python3 ใส่ source file ตรง ๆ ได้เลย ตอน develop ไม่มีขั้นตอน build

TypeScript
# TypeScript workflow
# tsc index.ts → compiles to index.js
# node index.js → runs the compiled output
# ts-node index.ts → shortcut for development
Python
# Python workflow
# python3 script.py → runs directly, no compile step
# python3 → opens the interactive REPL
# python3 -c "print(1)" → run a one-liner inline

ข้อนี้คือสิ่งที่ TypeScript developer สังเกตเห็นเป็นอย่างแรก เพราะ Python ใช้การย่อหน้า (4 spaces ตามข้อกำหนด) กำหนดขอบเขตของ block ไม่มี { } ให้ยึด และ colon (:) คือสิ่งที่เปิด block ใหม่เสมอ

TypeScript
// TypeScript
function classify(n: number): string {
if (n > 0) {
return "positive";
} else if (n < 0) {
return "negative";
} else {
return "zero";
}
}
Python
# Python — indentation IS the block
def 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)) # positive
print(classify(-3)) # negative
print(classify(0)) # zero

ย่อหน้าผิดเมื่อไหร่ก็เป็น syntax error ทันที โชคดีที่ editor สาย Python ส่วนใหญ่จัด indentation 4 spaces ให้อัตโนมัติอยู่แล้ว

TypeScript ยืดหยุ่นมาก จะใช้ class, functional composition, prototype chain หรือ plain object สลับกันไปมาก็ได้ ส่วน Python เชียร์ให้เหลือทางเดียวที่เป็นธรรมชาติที่สุด และชุมชนเรียกสไตล์นั้นว่า Pythonic — โค้ดที่กระชับ อ่านง่าย และใช้ฟีเจอร์ของภาษาตรงตามที่ออกแบบมา

TypeScript
// TypeScript: multiple ways to filter
const 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
# Python: list comprehension is the Pythonic way
nums = [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))

method ของ class ใน TypeScript ได้ this มาโดยปริยาย ส่วนใน Python ต้องประกาศ parameter self เป็น argument ตัวแรกให้ชัดเจน — interpreter ใส่ค่าให้เองตอนคุณเรียก method แต่คนที่ต้องเขียนประกาศไว้คือคุณ

TypeScript
// TypeScript: implicit this
class Counter {
private count: number = 0;
increment(): void {
this.count++; // 'this' is implicit
}
value(): number {
return this.count;
}
}
Python
# Python: explicit self
class 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 variables
x = 42
print(type(x).__name__) # int
x = "hello"
print(type(x).__name__) # str
# Significant indentation
def 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 comprehension
evens = [n for n in range(1, 11) if n % 2 == 0]
print("Evens:", evens)
# Explicit self
class 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())
ใน Python type ของค่าถูกเก็บไว้ที่ไหน?
อะไรเปิด indented block ใหม่ใน Python?
ทำไม Python class methods ต้องประกาศ `self` เป็น parameter แรก?
วิธีแบบ Pythonic ในการกรองเลขคู่จาก list คืออะไร?