Professional Documents
Culture Documents
มาเขียนไพธอนกันดีกว่า
มาเขียนไพธอนกันดีกว่า
ต ้นฉบับจาก howforge
สําหรับหัวข ้อตอนนีย
้ ังมีแค่คร่าวๆ
1. แนะนํ าภาษาไพธอน
2. พืน้ ฐาน
3. ตัวแปร
4. คําสัง่ ควบคุม
5. ฟั งก์ชนั่
6. โมดูล
7. อ๊อบเจ็กและคลาส
8. โมดูลมาตรฐาน
ไพธอนคืออะไร
ติดตัง้ ไพธอน
สวัสดีชาวโลก
ชนิดข ้อมูลพืน้ ฐาน
ตัวแปร
คําสัง่ ควบคุม
ฟั งก์ชนั่
อ๊อบเจ็กและคลาส
ไพธอนคืออะไร
Pythonic
Pythonic
วันนีล
้ องมาอธิบายคําว่า Pythonic กันดีกว่า พอดีมค ี นถามทีC
่ odenone แล ้วตอนนั น ้ ก็ตอบแบบสัน ้ ๆ ช่วงนีพ
้ อมีเวลาเลยลองมาศึกษาให ้ถ่องแท ้ดีกว่า ผม
เองก็ไม่รู ้จะอธิบายยังไงเหมือนกัน คล ้ายกับว่า Pythonic เป็ นปรัชญาชนิดหนึง่ เรียบง่าย ตรงไปตรงมา เข ้าใจอย่างไรก็เป็ นแบบนัน ี วามซับซ ้อน บาง
้ ไม่มค
คนก็บอกว่ามันคือ pseudocode ทีท ่ ํางานได ้จริงๆ ผมเคยลองเขียน pseudocode ด ้วย Python มันก็ดส ู ะอาดดี แต่กม็ ห
ี ลายคนไม่ชอบ เพราะไม่มป ี ี กกา {}
หรือ begin end แล ้วไม่สบายใจ เหมือนชีวต ิ ขาดอะไรไป โชคดีทผ ี่ มไม่ใช่คนแรกทีส ่ งสัย มีคนพยายามตอบหลายครัง้ ผมชอบคําอธิบายที่ Python Secret
Weblog มากทีส ่ ด
ุ เพราะมีตัวอย่างชัดเจน อย่างน ้อยก็เห็นแล ้วร ้อง อ๋อ ไม่ต ้องเสียเวลาจินตนาการ
เวลาใช ้ก็แบบนี้
int alpha;
int beta;
foo(&alpha,&beta);
alpha = [0]
beta = [0]
foo(alpha,beta)
alpha = alpha[0]
beta = beta[0]
ทีต
่ ้องทําแบบนีเ้ พราะว่า alpha กับ beta เป็ นตัวแปรทีเ่ ก็บค่าล ้วนๆ เวลาส่งเป็ นพารามิเตอร์จะส่งไปเฉพาะค่า ไม่มพ
ี อยเตอร์ซะด ้วย ถ ้าอยากจะทําตามนั น
้
จริงๆ ก็ต ้องใช ้ลิสต์เข ้ามาช่วยจําลองพอยเตอร์ จากโค ้ดข ้างบนจะเห็นว่ามันเลวร ้ายมาก ไม่มค ี วาม Pythonic เอาซะเลย ลองมาดูแบบนีบ ้ ้าง
def foo():
return 3,5.5
alpha,beta = foo()
เรียบง่าย ชัดเจน ไม่ได ้หมายความว่าภาษาอืน ่ ทําแบบนีไ ้ ม่ได ้ Ruby Perl PHP ทําแบบนีไ้ ด ้หมด ก็อย่างทีบ ่ อกตัง้ แต่ต ้น มันเป็ นปรัชญา Python ไม่ได ้
สนับสนุนให ้ทําแบบนี้ แต่มันทําได ้ และนอกจากนีท ้ ําแล ้วดีด ้วย เขียน Python มากๆ แล ้วจะรู ้สึกว่าวิธค
ี ด
ิ เปลีย
่ นไป กลายเป็ นคิดแบบ Python คนพวกนีจ ้ ะ
กลายเป็ น Pythonian ทุกภาษามีวถ ิ ขี องตนเอง นีค
่ อื วิถข
ี อง Python
o = A('1',2)
print o.a,o.b
o.b = 3
print o.a,o.b
ทิง้ ท ้ายเล็กน ้อย ถ ้าอยากใช ้ getter setter ใน Python จริงๆ ก็สามารถทําได ้ในแบบ Python
class A:
def __init__(self,a,b):
self.a = a
self.b = b
def get_a(self):
return self.a
def set_a(self,v):
self.a = v
a = property(get_a,set_a)
def get_b(self):
return self.b
def set_b(self,v):
self.b = v
b = property(,get_b,set_b)
a = A('1',2)
a.a = '2'
a.b = 3
print a.a,a.b
ก่อนทีจ
่ ะเริม
่ หัดไพธอนเราก็ต ้องมีไพธอนประจํ ากายเสียก่อนครับ สําหรับคนทีม ่ ล ิ ุกส์อยูใ่ นครอบครองหรือสามารถหามาใช ้ได ้สามารถข ้ามขัน
ี น ้ นี้ ไปเลยเลย
เพราะลินุกส์ทก ่ ล ้ว แต่สําหรับบางคนทีโ่ ชคร ้ายทีใ่ ช ้ FreeBSD ก็ต ้องลงไพธอนด ้วยครับ เพราะไม่ใช่ของปกติทม
ุ ตัวมีไพธอนอยูแ ี งั ้ แต่ลง รวมไปถึงคนทีใ่ ช ้
ี่ ต
วินโดส์ด ้วยเช่นกัน
เนือ
่ งจากไพธอนเป็ นภาษาแบบโอเพ่นซอร์สจึงทําให ้มีไพธอนหลายแบบ หรือจะพูดง่ายๆ ก็คอ
ื หลายยีห
่ ้อนั่นเอง โดยหลักๆ แล ้วมี 2 ยีห
่ ้อทีพ
่ บเห็นมาก
ทีส
่ ดุ ได ้แก่
1. Python by Python.org
2. ActivePython by ActiveState
การติดตงไพธอนบน
ั้ Mac OS X
มี 2 วิธค
ี อ
ื
สว ัสดีชาวโลก
กลับมาที่ Hello, World! กันต่อ คําสั่งทีใ่ ช ้ในนีม ี ําสัง่ เดียวคือ print คําสัง่ นีเ้ ป็ นคําสั่งพิเศษ ไม่เชิงเป็ นฟั งก์ชน
้ ค ั่ หรือในอีกมุมนึงมันเป็ นฟั งก์ชน
ั่ ทีอ
่ นุญาตให ้
ไม่ต ้องมีวงเล็บครับ ถัดมาคือคําว่า Hello, World! คํานีเ้ ป็ นสตริงก์ เพราะฉะนัน ้ ก็ต ้องอยูใ่ นเครือ
่ งหมายฟั งหนูซะให ้เรียบร ้อย มิฉะนั น
้ ไพธอนจะคิดว่าเป็ นตัว
แปรหรือฟั งก์ชน ั่
้ ฐาน
ชนิดข้อมูลพืน
1. จํานวนเต็ม (Integer)
2. จํานวนจริง (Float)
3. สตริง (String)
1. ลิสต์ (List)
2. ดิกชันนารี (Dictionary)
คําว่าซับซ ้อนหมายความว่าข ้อมูลเหล่านีจ ้ ะประกอบไปด ้วยข ้อมูลประเภทอืน ่ ายในแล ้วแต่การใช ้งาน เช่น ลิสต์ของจํ านวนเต็ม และดิกชันนารีของ
่ อยูภ
สตริง เป็ นต ้น ลิสต์ในทีน
่ ห
ี้ มายถึงอาเรย์ (Array) ในภาษาอืน่ นั่ นเอง แต่ถ ้าแบ่งประเภทใหญ่ๆ จะประกอบด ้วย
ต ัวเลข
1. จํานวนเต็ม (Integer)
2. จํานวนเต็มแบบยาว (Long Integer)
3. จํานวนจริง (Float)
4. จํานวนเชิงซ ้อน (Complex)
ลําด ับ
จ ับคู่
ชนิดข ้อมูลประเภทจับคู่ (Mapping) หรือ ดิกชัน ่ นารี (Dictionary) อาจรู ้จักกันในชืข ่ อง แฮช (Hash) อธิบายสัน ้ ๆ ได ้ว่าข ้อมูลประเภทนีค ื อาเรย์ทใี่ ช ้
้ อ
สามารถใช ้สตริงเป็ นคีย ์ (Key) ถึงข ้อมูลภายในได ้นั่ นเอง ปกติอาเรย์จะอ ้างถึงข ้อมูลเป็ นตัวเลข เริม
่ ตัง้ แต่ 0 ถึง n-1 เมือ ่ n คือความยาวของอาเรย์
่ นารีนม
หมายความว่าดิกชัน ี า่ 3 ค่า ได ้แก่ 1 2 และ 3 สามารถเข ้าถึงโดยใช ้สตริง 'a' 'b' และ 'c' เป็ นคียต
ี้ ค ์ ามลําดับ การเข ้าถึงจะใช ้เครือ
่ งหมาย [ ] คร่อม
เช่น
เนือ
่ งจากไพธอนเป็ นภาษาสคริปต์จงึ ไม่เน ้นชนิดของตัวแปร การไม่เน ้นไม่ได ้หมายความว่าตัวแปรในไพธอนไม่มช ี นิด ในความจริงแล ้วตัวแปรถ ้าพูดแบบ
ละเอียดชนิดของตัวแปรในไพธอนมีเพียงชนิดเดียว นั่นก็คอ ื พอยเตอร์ (Pointer) นั่นเอง สําหรับผู ้ทีเ่ คยมีประสบการณ์เขียนโปรแกรมด ้วยภาษาระดับกลาง
ถึงตํา่ เช่น ปาสคาล หรือซี เป็ นต ้น คําว่าพอยเตอร์อาจทําให ้ขยาด แต่ในไพธอนแล ้วพอยเตอร์เป็ นเรือ ่ งธรรมชาติทเี่ ข ้าใจได ้ง่ายกว่ามาก เพราะไม่ม ี
สัญลักษณ์และรูปแบบทีห ่ ลากหลายรวมถึงตัวแปรทุกตัวถือว่าเป็ นพอ ยเตอร์อยูแ ั สนกับชนิดของตัวแปร
่ ล ้วจึงไม่สบ
1. สะดวก ประหยัด
2. เปลีย
่ นชนิดของตัวแปรระหว่างการทํางานได ้
ในขณะทีข
่ ้อเสีย เช่น
ตัวอย่างตัวแปรตามชนิดข ้อมูล
ต ัวอย่างต ัวแปรตามชนิดข้อมูล
ว่ากันตามจริงแล ้วตัวแปรในไพธอนใช ้เหมือนกันหมดไม่มข ี ้อยกเว ้นกรณีพเิ ศษ ใดๆ สิง่ ทีแ ่ ตกต่างไปของวิธใี ช ้ขึน ้ กับชนิดข ้อมูลของตัวแปรนั น
้ มากกว่า
เพราะไพธอนเป็ นภาษาทีอ ่ งิ การเขียนโปรแกรมเชิงวัตถุ ด ้วยเหตุนต ่ ไี้ ปยังข ้อมูลเหล่านีจ
ี้ ัวแปรทีช ้ งึ มีสภาพคล ้ายกับอ๊อบเจ็กแต่ ไม่ใช่ออ๊ บเจ็ก อย่างไรก็ตาม
การคิดว่าชนิดข ้อมูลเป็ นอ๊อบเจ็กแบบพิเศษก็ไม่ผด ิ อะไรนัก แต่ชนิดข ้อมูลพืน ้ ฐานส่วนใหญ่ไม่มเี มธอดพิเศษเหมือนภาษาอืน ่ โดยเฉพาะอย่างยิง่ ตรรกะและ
ตัวเลข เมธอดทีใ่ ช ้บ่อยมักเกีย ่ วกับลําดับ และจับคู่ ตอนนีเ้ ราก็จะมาว่ากันด ้วยเรือ ่ งของเมธอดทีค ่ วรรู ้กันทีละชุด
การเขียนโปรแกรมทีท ่ ํางานตัง้ แต่บนลงล่างนัน้ ดูจะธรรมดาเกินไปสําหรับปั ญหา ยากๆ แต่ก็เป็ นไปได ้สําหรับงานทีไ่ ม่ซบั ซ ้อน การออกแบบด ้วยวิธ ี top-
down เป็ นกรรมวิธอ ี ย่างหนึง่ เพือ ั ซ ้อน และมันทํางานแบบบนลงล่าง อย่างไรก็ตามในทีส
่ ให ้โปรแกรมทีไ่ ด ้ไม่ซบ ุ แล ้วโปรแกรมมักซับซ ้อนเกินกว่าทีจ
่ ด ่ ะทํา
แบบบนลงล่างทัง้ หมดได ้ เมือ ่ โปรแกรมมีความซับซ ้อนจึงต ้องมีคําสั่งพิเศษสําหรับควบคุมการทํางาน หรือ Control Flow คําสัง่ ประเภทนีใ้ น ไพธอน จะถือ
เป็ นคําสัง่ เฉพาะ แบ่งเป็ น 2 ประเภทหลักๆ ได ้แก่
1. เงือ
่ นไข (Condition)
2. ลูป (Loop)
คําสัง่ เงือ
่ นไข
คําสัง่ ลูป
คําสง่ ั เงือ
่ นไข
คําสัง่ เงือ
่ นไข (Condition) ใน ไพธอน มีเพียงรูปแบบเดียวเท่านัน
้ แต่ก็เพียงพอสําหรับงานทุกประเภท ประยุกต์ได ้หลากหลายมาก มาเข ้าเรือ
่ งกันดีกว่า
คําสัง่ เงือ ้ ะมีสว่ นประกอบ 3 ส่วน ได ้แก่
่ นไขนีจ
1. เงือ
่ นไข
2. คําสัง่ เมือ่ ตรงตามเงือ
่ นไข
3. คําสัง่ เมือ
่ ไม่ตรงตามเงือ่ นไข ส่วนนีอ
้ าจจะมีหรือไม่มก
ี ็ได ้
เมือ
่ นํ ามารวมกันจะอยูใ่ นรูปแบบด ้านล่าง
if expression:
statement1
statement2
1. for
2. while
ก่อนอืน ่ บอกจุดจบของคําสั่งทีม
่ จะเห็นว่าคล ้ายคล ้าย if ครับ มี colon : เพือ ี ําสัง่ ย่อย จุดทีน
่ ค ่ ่าสนใจอยูท
่ ี่ for i in lists นีแ
่ หละครับ นีค
่ อ
ื รูปแบบทีแ
่ น่นอน
ตายตัว หมายความว่า การวนรอบแต่ละครัง้ ค่า i จะเปลีย ่ นไป โดยค่าทีอ
่ ยูใ่ น i จะถูกนํ ามาจาก ลิสต์ ทีช ่ อื่ lists ตามลําดับจนหมด ยกตัวอย่างเช่น
for i in [0,1,2,3,4]:
print ’i’,i
จะได ้ผลดังนี้
i0
i1
i2
i3
i4
อย่าพึง่ ตกใจว่าวิธน ี จ
ี้ ะบานปลายถ ้าต ้องลูปเลข 1 ถึง 1000000 เพราะต ้องมีลส ิ ต์ใหญ่มหาศาล และก็ไม่จําเป็ นต ้องมีซะด ้วย เพราะมันเป็ นเลขเรียงกัน ใช่
แล ้วครับ ไม่จําเป็ น ไพธอน มีวธิ ท
ี งี่ า่ ยกว่า ในกรณีของ for นี้ มันเป็ นการ for ลงไปในชุดเลขทีเ่ รียงกัน เพราะฉะนั น ้ ไพธอน จึงมีฟังก์ชนั่ เอาไว ้สําหรับสร ้าง
ลิสต์ โดยเฉพาะ 2 คําสัง่ ได ้แก่ range() และ xrange() สําหรับตัวอย่างทีผ ่ า่ นมา สามารถเขียนแบบ ไพธอน ได ้ดังนี้
for i in range(5):
print ’i’,i
จริงๆ แล ้ว range() กับ xrange() ให ้ผลเหมือนกันทุกประการ แต่ตา่ งกันทีเ่ วลาทําไปใช ้งาน โดย range() จะสร ้าง ลิสต์ ตามทีร่ ะบุแล ้วคืน ลิสต์ นัน
้
กลับมาทันที แต่ xrange() จะไม่ได ้สร ้าง ลิสต์ ทัง้ หมดขึน
้ มาในทีเดียว แต่ละส่งให ้ทีละค่า วิธข
ี อง xrange() นีเ้ รียกว่า Generator ครับ เหมาะสําหรับงาน
ทีม
่ ข
ี ้อมูลจํานวนมากและไม่จําเป็ นต ้องเก็บทุกอย่างในหน่วยความจําในครัง้ เดียว
เงือ
่ นไข expression มีลักษณะเดียวกับใน if เพราะฉะนั น
้ ตัวอย่างด ้านบนจะเขียนด ้วย while ได ้ดังต่อไปนี้
i=0
while i < 5:
print ’i’,i
i += 1
่ั
ฟังก์ชน
สําหรับการเขียนโปรแกรม ไม่วา่ โปรแกรมนั น ้ จะแปลกหรือซับซ ้อนแค่ไหน สุดท ้ายโปรแกรมทุกโปรแกรมก็ต ้องใช ้เพียงแค่ ตัวแปร และ คําสัง่ ควบคุม เพียง
สองส่วนประกอบนีก ้ ็สามารถเขียนโปรแกรมใดๆ ก็ได ้ อย่างไรก็ตามโปรแกรมทีซ ั ซ ้อนไม่จะมีลักษณะพิเศษทีพ
่ บ ่ ่วงท ้ายมาด ้วยเสมอ นั่นคือ โปรแกรมใดๆ
จะมีสว่ นทีซ่ ํ้ากันเสมอ ถ ้าส่วนทีซ
่ ํ้ากันต ้องทําซํ้าๆ ติดๆ กันก็จะกลายเป็ น ลูป แต่ถ ้าไม่ได ้ซํ้าติดๆ กัน ก็จะทําให ้ไม่สามารถเขียนเป็ น ลูป ได ้ โปรแกรมส่วน
้ ก็จะซํ้ากันโดยปริยาย และแล ้วก็ถงึ บทพระเอกของ ฟั งก์ชน
นัน ั่
ั่ นีจ
ฟั งก์ชน ้ ะรับ พารามิเตอร์ 1 ตัว และนํ ามาพิมพ์ตอ
่ ท ้ายคําว่า Hello, World โดยทีไ่ ม่สนว่า พารามิเตอร์นัน
้ จะเป็ นชนิดอะไร ในกรณีทต
ี่ ้องการส่ง
พารามิเตอร์ มากกว่า 1 ตัวก็สามารถทําได ้โดยใช ้ comma , ขัน ้ ทัง้ ตอนประกาศและเรียกใช ้
def hello(s,i):
print s,i
อ๊อบเจ็ กและคลาส
หนึง่ ในคุณสมบติทด ี่ ท
ี ส
ี่ ด
ุ ของไพธอนก็คอื คลาส (Class) นีเ่ อง คลาสเป็ นความสามารถทีแ ่ ถมมากับหลักการ Object-Oriented Programming ซึง่ เหมาะ
กับการพัฒนาโปรแกรมทัง้ ขนาดเล็ก ขนาดกลาง และขนาดใหญ่ มีจด ุ เด่นทีน
่ ่าสนใจของคลาสก็คอ
ื การแบ่งปั ญหาใหญ่ให ้เล็กลงเพือ
่ แก ้ไขในขอบเขตที่
จํากัด ทัง้ ยังช่วยให ้การทดสอบง่ายขึน ้ อีกด ้วย
กลับมาดูคลาสในไพธอนดีกว่า เริม
่ จากคลาสง่ายๆ
class Person:
pass
p = Person()
print p.name,p.age
ซึง่ จะรับประกันได ้ว่า Person ทุกอ็อบเจ็กจะมี name และ age เสมอ แต่ยังไม่สามารถกําหนดค่าเริม
่ ต ้นแบบสวยๆ ได ้
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
p = Person('Alice',8)
def show(self):
print '%s is %d years old.' % (self.name,self.age)
p = Person('Alice',8)
p.show()
def show(self):
print '%s is %d years old.' % (self.name,self.age)
p = Person(name='Alice',age=8)
p.show()
def __init__(self,**kw):
self.__dict__.update(kw)
def show(self):
print '%s is %d years old.' % (self.name,self.age)
p = Person(name='Alice',age=8)
p.show()
ผมมองว่าไม่ใช่ class นะ แต่เป็ น object ต่างหาก เพราะว่าไม่ม ี information hiding เลย ใครจะล ้วงเอาอะไรไป หรือลบ attribute ของ object ก็ได ้ เช่น
>>> class Person2:
... def __init__(self):
... self.name = "me"
...
>>> p = Person2()
>>> p.name
'me'
>>> del p.name
>>> p.name
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: Person2 instance has no attribute 'name'
นอกจากนั น
้ ถ ้าเราสร ้างคลาสแบบนี้
>>> class Person:
... name = "me"
... age = 20
แถมคําถามหน่อย...
่ วรใช ้แบบ Person หรือแบบ Person2 (แบบทีไ่ ม่ใช ้ __init__ กับแบบทีใ่ ช ้ __init__ ตามลําดับ) ดีครับ?
เวลา define class นีค