ใช้ไพธอนทำ...
ลิงก์รอศึกษา
เอามาจาก Python Tutorial
ตั้งใจเขียนให้อ่านสนุก ๆ นะครับ ห้ามจริงจังเด็ดขาด
ไพธอนเป็น ...
สำหรับเดเบียน ไพธอนจะถูกติดตั้งมาเป็นค่าปริยาย แต่หากถูกถอดออกไปแล้ว ก็สามารถติดตั้งใหม่ด้วยคำสั่ง
$ sudo aptitude install python
2.1 เรียกใช้ตัวแปลบรรทัดคำสั่ง (Invoking the Interpreter)
2.2 ตัวแปลคำสั่งและสภาพแวดล้อม (The Interpreter and Its Environment)
ในเดเบียนตัวโปรแกรมไพธอนจะอยู่ที่ /usr/bin/python ซึ่งจะเป็นลิงก์โยงไปหาตัวไพธอนรุ่นที่เราติดตั้งจริง ๆ เช่น
$ which python /usr/bin/python $ ls -l /usr/bin/python lrwxrwxrwx 1 root root 9 2006-12-26 19:18 /usr/bin/python -> python2.4
จะเห็นว่ารุ่นของไพธอนตามตัวอย่าง เป็นรุ่น 2.4
ซึ่งไดเรกทอรี่ /usr/bin จะอยู่ในพาธการค้นหาโปรแกรมอยู่แล้ว ดังนั้นเราสามารถเรียกใช้ได้ง่าย ๆ ว่า
$ python
สำหรับลินุกซ์ดิสโตรอื่นก็คล้าย ๆ กัน
ในวินโดวส์ เมื่อติดตั้งไพธอนเสร็จแล้ว ตัวโปรแกรมจะไปอยู่ที่ C:\Python24 ซึ่งเราอาจต้องเพิ่มในพาธเอง ด้วยการเข้าสู่ Command Prompt และพิมพ์ดังนี้
set path=%path%;C:\python24
ทั้งหมดนี้เป็นการเรียกใช้ตัวแปลบรรทัดคำสั่งของไพธอน ซึ่งจะทำให้เราสามารถใช้งานแบบโต้ตอบกับตัวแปลภาษาได้
แต่ยังมีอีกกรณีหนึ่งคือ หากเราต้องการเพียงแค่ทดลองเพียงคำสั่งเดียวแล้วออกจากไพธอนเลย เราอาจใช้รูปแบบเป็น python -c command [arg] เช่น
$ python -c 'print "abcd"' abcd
เมื่อเรียกใช้ตัวแปลบรรทัดคำสั่ง ค่าตามหลังที่เราส่งผ่านให้กับโปรแกรม จะถูกเก็บไว้ที่ตัวแปร sys.argv โดย...
python : sys.argv[0] จะเป็นสตริงก์ว่างpython - : sys.argv[0] จะบรรจุค่า "-"-c หรือ -m : sys.argv[0] จะเก็บค่า "-c" และชื่อมอดูลตามลำดับ ค่าอื่นหลังจากนี้ จะถูกเก็บไว้ในตัวแปร sys.argv เพื่อให้คำสั่งหรือมอดูลได้เรียกใช้งานต่อไปพร้อมต์หลัก (Primary prompt) คือ >>>
$ python Python 2.4.4 (#2, Apr 5 2007, 20:11:18) [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>>
แต่หากยังไม่จบบล๊อก จะใช้พร้อมต์ตาม (Secondary promt) คือ ... ดังนี้
>>> the_world_is_flat = 1 >>> if the_world_is_flat: ... print "Be careful not to fall off!" ... Be careful not to fall off!
เมื่อเกิดข้อผิดพลาด ไพธอนจะรายงานข้อผิดพลาดและรายทางของการผิดพลาด โดย
รายงานความผิดพลาดทั้งหมดจะถูกส่งไปยังสายการรายงานข้อผิดพลาดของระบบ (standard error stream) และการแสดงผลก็จะถูกส่งไปยังเอาต์พุตของระบบเช่นกัน
การกดคีย์เพื่อขัดจังหวะ เช่น Control-C หรือ DEL จะ...
KeyboardInterrupt จะถูกยกขึ้นมา ซึ่งเราสามารถจัดการได้โดยผ่านประโยคคำสั่ง tryแค่เติม Hash bang ที่บรรทัดแรกของสคริปต์ ก็จะทำให้สคริปต์สามารถรันได้
#! /usr/bin/env python
อย่าลืมเปลี่ยนโหมดให้รันได้ด้วย
$ chmod +x myscript.py
หากมีส่วนของโค๊ดที่ไม่ใช่ภาษาอังกฤษล้วน ควรแจ้งการเข้ารหัสอักขระด้วย ด้วยการเติมต่อจากบรรทัดแรกว่า
# -*- coding: encoding -*-
สามารถดูรหัสอักขระทั้งหมดที่ Python Library Reference ในหัวข้อ codecs
เช่น ถ้าจะกำหนดค่าตัวแปรให้มีสัญญลักษณ์การเงินยูโร เราอาจเลือกใช้การเข้ารหัสอักขระเป็น ISO-8859-15 (ค่า ordinal คือ 164) ซึ่งในสคริปต์นี้จะพิมพ์ค่า 8364 ซึ่งเป็นค่ายูนิโค๊ดของสัญญลักษณ์ยูโร
# -*- coding: iso-8859-15 -*- currency = u"€" print ord(currency)
แต่สำหรับยุคนี้ ควรเลือกใช้ UTF-8 ดีกว่าเยอะ เพราะรองรับอักขระทุกตัวในโลก
ในการใช้งานหมวดโต้ตอบ บางครั้งอาจต้องตั้งค่าเริ่มต้นให้ระบบ โดยการใส่ชื่อโปรแกรมที่ต้องการรันในการเริ่มต้นให้กับตัวแปรแวดล้อมชื่อ PYTHONSTARTUP (คล้ายกับการตั้งค่าไฟล์ .profile ในลินุกซ์)
เราสามารถขยายความสามารถนี้ โดยให้ไฟล์เริ่มต้นหลักมาดูในไดเรคทอรี่ปัจจุบันก่อน ว่ามีไฟล์ที่มีชื่อตามที่เรากำหนดหรือไม่ ถ้ามีก็จะรันตามที่เรากำหนดไว้ เช่นถ้ากำหนดให้ใช้ชื่อว่า .pythonrc.py ก็ใช้คำสั่งว่า "if os.path.isfile('.pythonrc.py'): execfile('.pythonrc.py')" เป้นต้น
การสร้างไฟล์เริ่มต้นทำได้โดยบรรจุคำสั่งนี้ในสคริปต์
import os
filename = os.environ.get('PYTHONSTARTUP')
if filename and os.path.isfile(filename):
execfile(filename) 3.1 ใช้งานเป็นเครื่องคิดเลข (Using Python as a Calculator)
3.2 ลองเขียนสักสคริปต์นึง (First Steps Towards Programming)
ตัวอย่างจะใช้เครื่องหมาย # แทนคอมเมนต์
เช่น
# this is the first comment
SPAM = 1 # and this is the second comment
# ... and now a third!
STRING = "# This is not a comment."ในหมวดโต้ตอบ เราใช้แทนเครื่องคิดเลขได้เลย เช่น
>>> 2+2 4 >>> # This is a comment ... 2+2 4 >>> 2+2 # and a comment on the same line as code 4 >>> (50-5*6)/4 5 >>> # Integer division returns the floor: ... 7/3 2 >>> 7/-3 -3
กำหนดค่าให้ตัวแปรด้วย = ตามปกติ
>>> width = 20 >>> height = 5*9 >>> width * height 900
กำหนดทีละหลายตัวแปรพร้อมกันก็ได้
>>> x = y = z = 0 # Zero x, y and z >>> x 0 >>> y 0 >>> z 0
รองรับทศนิยมลอยด้วย โดยมีหลักว่า ถ้าต้นทางเป็นจำนวนเต็ม ผลจะเป็นจำนวนเต็มด้วย ถ้าต้นทางเป็นทศนิยมลอย ผลจะเป็นทศนิยมลอยด้วย (ถ้าผสมกันก็จะเป็นทศนิยมลอยเช่นกัน)
>>> 3 * 3.75 / 1.5 7.5 >>> 7 / 2 3 >>> 7.0 / 2 3.5
จำนวนเชิงซ้อนก็ได้ โดยตัวเลขจินตภาพจะต้องต่อท้ายด้วย "j" หรือ "J" โดยมีรูปแบบเป็น "(real+imagj)" หรือเขียนแบบฟังก์ชั่นว่า "complex(real, imag)"
>>> 1j * 1J (-1+0j) >>> 1j * complex(0,1) (-1+0j) >>> 3+1j*3 (3+3j) >>> (3+1j)*3 (9+3j) >>> (1+2j)/(1+1j) (1.5+0.5j)
ตัวเลขในจำนวนเชิงซ้อน จะถูกตีความเป็นทศนิยมลอยเสมอ และสามารถแยกตัวเลขจริงกับตัวเลขจินตภาพด้วยการเขียนในรูปแบบออปเจคต์คือ z.real และ z.imag
>>> a=1+0.5j >>> a.real 1.0 >>> a.imag 0.5
ไม่สามารถใช้ฟังก์ชั่นการแปลงตัวเลขปกติ คือ float(), int() และ long() กับจำนวนเชิงซ้อนได้
แต่สามารถใช้ฟังก์ชั่น abs(z) หาค่าสัมบูรณ์ และใช้ z.real หาค่าจำนวนจริงของ z ได้
>>> a=3.0+4.0j >>> float(a) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: can't convert complex to float; use abs(z) >>> a.real 3.0 >>> a.imag 4.0 >>> abs(a) # sqrt(a.real**2 + a.imag**2) 5.0
พิเศษสำหรับหมวดโต้ตอบ ค่าที่ถูกพิมพ์ออกมาเป็นครั้งสุดท้าย จะถูกเก็บไว้ในตัวแปรพิเศษคือ _ เราอาจนำตัวแปรนี้ไปใช้ในการคำนวนค่าต่อ ๆ ไป
>>> tax = 12.5 / 100 >>> price = 100.50 >>> price * tax 12.5625 >>> price + _ 113.0625 >>> round(_, 2) 113.06
*** เนื่องจาก _ เป็นตัวแปรพิเศษดังกล่าว ดังนั้นเพื่อป้องกันความผิดพลาด จึงไม่ควรกำหนดค่าให้มัน ควรใช้เป็นตัวแปรเฉพาะตามวัตถุประสงค์ของไพธอนเท่านั้น
สามารถใช้งานสตริงก์ได้ทั้งอัญประกาศเดี่ยวและคู่ (Single & Double quote)
>>> 'spam eggs' 'spam eggs' >>> 'doesn\'t' "doesn't" >>> "doesn't" "doesn't" >>> '"Yes," he said.' '"Yes," he said.' >>> "\"Yes,\" he said." '"Yes," he said.' >>> '"Isn\'t," she said.' '"Isn\'t," she said.'
ใช้สตริงก์แบบหลายบรรทัด โดย...
\ (Backslash) ในการแยก เช่น>>> hello = "This is a rather long string containing\n\
... several lines of text just as you would do in C.\n\
... Note that whitespace at the beginning of the line is\
... significant."
>>> print hello
This is a rather long string containing
several lines of text just as you would do in C.
Note that whitespace at the beginning of the line is significant.r นำหน้าเครื่องหมายอัญประกาศ ซึ่งก็จะให้ผลแบบดิบ ๆ>>> hello = r"This is a rather long string containing\n\ ... several lines of text much as you would do in C." >>> print hello This is a rather long string containing\n\ several lines of text much as you would do in C.
""" หรือ ''' อันนี้ใช้ง่ายแบบธรรมชาติ>>> print """
... Usage: thingy [OPTIONS]
... -h Display this usage message
... -H hostname Hostname to connect to
... """
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect toที่สำคัญคือ เริ่มต้นด้วยอัญประกาศแบบไหน ก็ต้องปิดท้ายด้วยอัญประกาศแบบนั้นเสมอ
ใช้ + ในการเชื่อมสตริงก์ และ * ในการเชื่อมแบบซ้ำ ๆ
>>> word = 'Help' + 'A' >>> word 'HelpA' >>> '<' + word*5 + '>' '<HelpAHelpAHelpAHelpAHelpA>'
ในหมวดโต้ตอบนี้ ช่องว่างระหว่างสตริงก์ถูกประมวลผลเป็นการเชื่อมสคริงก์ แต่ใช้ได้กับสคริงก์อย่างเดียว ฟังกืชั่นไม่เกี่ยว
>>> 'str' 'ing' # <- This is ok
'string'
>>> 'str'.strip() + 'ing' # <- This is ok
'string'
>>> 'str'.strip() 'ing' # <- This is invalid
File "<stdin>", line 1, in ?
'str'.strip() 'ing'
^
SyntaxError: invalid syntax
สตริงก์ทำตัวเป็น อาเรย์ของอักขระ ดังนั้นจึงสามารถอ้างถึงแบบอาเรย์ได้ โดยอ้างเป็นช่วงด้วย : (colon) ซึ่งไพธอนเรียกช่วงของสตริงก์นี้ว่าสไลซ์ (slice)
>>> word[4] 'A' >>> word[0:2] 'He' >>> word[2:4] 'lp'
ถ้าละเลย ไม่ใส่ค่าดัชนี ถ้าเป็นดัชนีข้างหน้า จะถูกตีความเป็นศูนย์ และตัวหลังจะถูกตีความเป็นความยาวสตริงก์
>>> word[:2] # The first two characters 'He' >>> word[2:] # Everything except the first two characters 'lpA'
สตริงก์ในไพธอนไม่เหมือนกับภาษาซี ไพธอนไม่สามารถเปลี่ยนค่าสคริงก์โดยอ้างจากดัชนีได้
>>> word[0] = 'x' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: object doesn't support item assignment >>> word[:1] = 'Splat' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: object doesn't support slice assignment
แต่ก็สร้างใหม่ได้ไม่ยาก
>>> 'x' + word[1:] 'xelpA' >>> 'Splat' + word[4] 'SplatA' >>> x = word[:] >>> x = 'Splat' + x[4] >>> x 'SplatA'
ลูกเล่นเล็กน้อย ให้ผลเป็น s เหมือนเดิม
>>> word[:2] + word[2:] 'HelpA' >>> word[:3] + word[3:] 'HelpA'
ดัชนีที่มีค่านอกช่วงที่มีจริง ไพธอนจะแสดงเป็นอักขระว่างให้ โดยไม่รายงานความผิดพลาด
>>> word[1:100] 'elpA' >>> word[10:] '' >>> word[2:1] ''
ดัชนีเป็นค่าลบ จะเป็นการนับจากขวามาซ้าย
>>> word[-1] # The last character 'A' >>> word[-2] # The last-but-one character 'p' >>> word[-2:] # The last two characters 'pA' >>> word[:-2] # Everything except the last two characters 'Hel'
ยกเว้น -0 มีค่าเท่ากับ 0 จึงนับจากซ้ายเป็นปกติ
>>> word[-0] # (since -0 equals 0) 'H'
ถ้าระบุดัชนีเป็นช่วง ไพธอนจะจัดการค่าที่ไม่เป็นจริงให้ทั้งหมด แต่ถ้าใช้ดัชนีตัวเดียว ถ้าค่าดัชนีไม่เป็นจริง ไพธอนจะแสดงค่าผิดพลาด
>>> word[-100:] 'HelpA' >>> word[-10] # error Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: string index out of range
เทคนิกการจำเรื่องช่วงดัชนีคือ ให้คิดว่าดัชนีเป็นค่าที่อยู่ระหว่างอักขระ ที่ซ้ายสุดเป็น 0 และขวาสุดเป็นขนาดสตริงก์
+---+---+---+---+---+ | H | e | l | p | A | +---+---+---+---+---+ 0 1 2 3 4 5 -5 -4 -3 -2 -1
สำหรับดัชนีที่เป็นค่าบวก ขนาดของสไลซ์คือผลต่างของค่าตัวเลขดัชนี เช่นขนาดของ word[1:3] คือ 2
เราหาขนาดของสตริงก์ด้วยฟังก์ชั่น len()
>>> s = 'supercalifragilisticexpialidocious' >>> len(s) 34
ดูเพิ่มเติม
เรื่อง
เริ่มใช้ในไพธอนรุ่น 2.0 ในการจัดการข้อมูลแบบยูนิโค๊ด (ดู http://www.unicode.org/)
ใช้งานเหมือนสตริงก์ปกติ เวลาเขียนใช้ u นำหน้าอัญประกาศ
>>> u'Hello World !' u'Hello World !'
ถ้าอักขระยูนิโค๊ดตัวไหนพิมพ์ยาก อาจใช้ \u (Python Unicode-Escape) นำหน้า
แสดงตัวอย่างเป็นอักขระเคาะวรรค (space) คือ \u0020
>>> u'Hello\u0020World !' u'Hello World !'
ในการใช้สตริงก์ดิบกับยูนิโค๊ด ใช้ ur นำหน้า และต้องใส่อักขระ \ สองตัว ไม่งั้นจะตีความเป็น Python Unicode-Escape ดูยุ่งยากเล็กน้อย แต่จะมีประโยชน์สำหรับการใช้งาน regular expresstion
>>> ur'Hello\u0020World !' u'Hello World !' >>> ur'Hello\\u0020World !' u'Hello\\\\u0020World !'
จริง ๆ แล้ว ไพธอนเก็บข้อมูลสตริงก์เป็นอักขระยูนิโค๊ดอยู่แล้ว (อาจเปลี่ยนแปลงในรุ่นหน้า คือรุ่น 3.0) ดังนั้นการใช้ฟังก์ชั่น str() กับอักขระยูนิโค๊ด จึงแสดงข้อผิดพลาด เว้นเสียแต่ว่าอักขระเหล่านั้นมีรหัส ASCII น้อยกว่า 127 คือเป็นภาษาอังกฤษธรรมดา
>>> u"abc" u'abc' >>> str(u"abc") 'abc' >>> u"äöü" u'\xe4\xf6\xfc' >>> str(u"äöü") Traceback (most recent call last): File "<stdin>", line 1, in ? UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
การแปลงการเข้ารหัสอักขระเป็นรหัสอักขระต่าง ๆ เราใช้ฟังก์ชั่น encode()
>>> u"äöü".encode('utf-8')
'\xc3\xa4\xc3\xb6\xc3\xbc'เป็นการแปลงสตริงก์ u"äöü" ไปเป้นสตริงก์แบบ utf-8
และใช้ฟังก์ชั่น unicode() ในการแปลงกลับ
>>> unicode('\xc3\xa4\xc3\xb6\xc3\xbc', 'utf-8')
u'\xe4\xf6\xfc'ข้อมูลลิสต์ถือเป็นข้อเด่นที่สุดข้อหนึ่งของไพธอน เป็นการเอาข้อมูลมาจัดให้อยู่ในกลุ่มเดียวกัน ภายใต้เครื่องหมายวงเล็บ [] โดยข้อมูลย่อยไม่จำเป็นต้องเป็นชนิดเดียวกัน
>>> a = ['spam', 'eggs', 100, 1234] >>> a ['spam', 'eggs', 100, 1234]
การใช้ดัชนีในการอ้างถึงข้อมูลย่อยภายใน ใช้งานคล้ายกับสตริงก์
>>> a[0] 'spam' >>> a[3] 1234 >>> a[-2] 100 >>> a[1:-1] ['eggs', 100] >>> a[:2] + ['bacon', 2*2] ['spam', 'eggs', 'bacon', 4] >>> 3*a[:3] + ['Boo!'] ['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boo!']
แต่ต่างจากสตริงก์ตรงที่ข้อมูลย่อยภายในสามารถเปลี่ยนแปลงค่าได้ โดยการอ้างจากดัชนี
>>> a ['spam', 'eggs', 100, 1234] >>> a[2] = a[2] + 23 >>> a ['spam', 'eggs', 123, 1234] >>> a[2] = 10 >>> a ['spam', 'eggs', 10, 1234]
กำหนดค่าเป็นช่วงสไลซ์ก็ได้
>>> # Replace some items: ... a[0:2] = [1, 12] >>> a [1, 12, 123, 1234] >>> # Remove some: ... a[0:2] = [] >>> a [123, 1234] >>> # Insert some: ... a[1:1] = ['bletch', 'xyzzy'] >>> a [123, 'bletch', 'xyzzy', 1234] >>> # Insert (a copy of) itself at the beginning ... a[:0] = a >>> a [123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234] >>> # Clear the list: replace all items with an empty list ... a[:] = [] >>> a []
ใช้ฟังก์ชั่น len() ในการหาขนาดลิสต์ (จำนวนสมาชิก)
>>> len(a) 8
ซ้อนลิสต์ในลิสต์ก็ได้
>>> q = [2, 3]
>>> p = [1, q, 4]
>>> len(p)
3
>>> p[1]
[2, 3]
>>> p[1][0]
2
>>> p[1].append('xtra') # See section 5.1
>>> p
[1, [2, 3, 'xtra'], 4]
>>> q
[2, 3, 'xtra']
จากตัวอย่างนี้ ตัวแปร p[1] กับตัวแปร q เป็นออปเจกต์อันเดียวกัน (การใช้ลิสต์ต้องระวังตรงนี้นิดนึง)
การใช้งานไพธอนง่ายตรงนี้ คือเราจะเขียนโค๊ดเล็ก ๆ แล้วก็จับมาต่อ ๆ กันไป กลายเป็นสคริปต์ที่ซับซ้อนสำหรับใช้งานจริง
เริ่มด้วยโค๊ดอมตะ อนุกรมฟิโบแนคซี่ (Fibonacci)
>>> # Fibonacci series: ... # the sum of two elements defines the next ... a, b = 0, 1 >>> while b < 10: ... print b ... a, b = b, a+b ... 1 1 2 3 5 8
ความรู้ใหม่
a คือ 0 และ b คือ 1while คำสั่งนี้จะตีความว่า นิพจน์หลังคำสั่ง while จะเป็นอะไรก็ได้ที่ไม่ใช่ศุนย์หรือค่าว่าง จะเป็นจริงเสมอ โดยที่การเปรียบเทียบจะใช้สัญญลักษณ์เหมือนภาษาซี คือ < คือน้อยกว่า > คือมากกว่า == คือเท่ากันกับ <= คือน้อยกว่าหรือเท่ากับ >= คือมากกว่าหรือเท่ากับ และ != คือไม่เท่ากับprint มีข้อพิเศษคือ
>>> i = 256*256 >>> print 'The value of i is', i The value of i is 65536
>>> a, b = 0, 1 >>> while b < 1000: ... print b, ... a, b = b, a+b ... 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
4.1 ประโยค if ( if Statements)
4.2 ประโยค for ( for Statements)
4.3 ฟังก์ชั่น range() (The range() Function)
4.4 คำสั่ง break และ continue และวลี else สำหรับการวนรอบ ( break and continue Statements, and else Clauses on Loops)
4.5 คำสั่ง pass ( pass Statements)
4.6 นิยามฟังก์ชั่น (Defining Functions)
4.7 เพิ่มเติมเรื่องฟังก์ชั่น (More on Defining Functions)
while แล้ว บทนี้เรามารู้จักคำสั่งควบคุมให้มากขึ้น
if ( if Statements)>>> x = int(raw_input("Please enter an integer: "))
>>> if x < 0:
... x = 0
... print 'Negative changed to zero'
... elif x == 0:
... print 'Zero'
... elif x == 1:
... print 'Single'
... else:
... print 'More'
...มี elif กี่ตัวก็ได้ และมี else หรือไม่มีก็ได้ (ภาษาอื่นอาจมี switch และ case แต่ไพธอนใช้ if อย่างเดียว)
for ( for Statements)for ของไพธอน ต่างจากภาษาอื่นเล็กน้อย ตอนวนรอบ แทนที่จะใช้ตัวนับซึ่งเป็นตัวเลข ไพธอนกลับใช้ลำดับแทน (เช่น สตริงก์ ลิสต์ หรือทูเปิล)
>>> # Measure some strings: ... a = ['cat', 'window', 'defenestrate'] >>> for x in a: ... print x, len(x) ... cat 3 window 6 defenestrate 12
range() (The range() Function)ใช้สร้างลิสต์จากช่วงของตัวเลขจำนวนเต็ม
แบบง่าย
>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
อาจกำหนดเป็นช่วง
>>> range(5, 10) [5, 6, 7, 8, 9]
หรือแบบกำหนดขนาดขั้นของการเพิ่มด้วย
>>> range(0, 10, 3) [0, 3, 6, 9] >>> range(-10, -100, -30) [-10, -40, -70]
ใช้ร่วมกับ len() กับลิสต์ (การทำงานกับลิสต์แบบอ้างอิงจากดัชนี จะใช้วิธีนี้เป็นปกติ)
>>> a = ['Mary', 'had', 'a', 'little', 'lamb'] >>> for i in range(len(a)): ... print i, a[i] ... 0 Mary 1 had 2 a 3 little 4 lamb
break และ continue และวลี else สำหรับการวนรอบ ( break and continue Statements, and else Clauses on Loops)คำสั่ง break ส่งผลให้หลุดจากวงรอบที่คำสั่งนี้บรรจุอยู่
ส่วน continue จะมีผลให้หยุดการทำงานที่จุดนั้น แล้วกลับไปเริ่มวนรอบใหม่
วลี else ใช้สำหรับเมื่อหลุดจากการวนแล้ว จะทำภายในบล๊อกนี้หนึ่งครั้ง ยกเว้นถ้าพบคำสั่ง break
>>> for n in range(2, 10): ... for x in range(2, n): ... if n % x == 0: ... print n, 'equals', x, '*', n/x ... break ... else: ... # loop fell through without finding a factor ... print n, 'is a prime number' ... 2 is a prime number 3 is a prime number 4 equals 2 * 2 5 is a prime number 6 equals 2 * 3 7 is a prime number 8 equals 2 * 4 9 equals 3 * 3
pass ( pass Statements)คำสั่ง pass ไม่ทำอะไรเลย แต่มีไว้เผื่อเวลาเราวางโครงสร้างโค๊ดไว้แล้ว แต่ยังไม่ได้เขียนท่อนนั้น ก็บรรจุคำสั่งนี้ไว้เพื่อให้สามารถทดสอบการรันได้
>>> while True: ... pass # Busy-wait for keyboard interrupt ...
เอาตัวอย่างในการเขียนอนุกรมฟิโบแนคซี่มาเขียน
>>> def fib(n): # write Fibonacci series up to n ... """Print a Fibonacci series up to n.""" ... a, b = 0, 1 ... while b < n: ... print b, ... a, b = b, a+b ... >>> # Now call the function we just defined: ... fib(2000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
ฟังก์ชั่น ขึ้นต้นด้วย def ตามด้วยชื่อฟังก์ชั่นและวงเล็บซึ่งบรรจุอาร์กิวเมนต์ หลังจากนี้จะเป็นบล๊อกที่ต้องเยื้องย่อหน้า
บรรทัดพิเศษต่อจากชื่อฟังก์ชั่น อาจใส่คำอธิบายการทำงานของฟังก์ชั่นได้เลย ซึ่งไพธอนจะไม่ตีความเป็นโค๊ดที่จะรัน บรรทัดนี้เรียกว่า docstring
ตัวแปรในฟังก์ชั่นจะถือเป็นตัวแปรท้องถิ่นทั้งหมด เว้นแต่เรากำหนดให้เป็นตัวแปรร่วม ซึ่งต้องกำหนดด้วยคำสั่ง global
การส่งผ่านค่าตัวแปร จะถือเป็นการส่งผ่านโดยค่าทั้งหมด (pass by value)
ชื่อฟังก์ชั่นสามารถถูกกำหนดค่าให้กับตัวแปรได้
>>> fib <function fib at 10042ed0> >>> f = fib >>> f(100) 1 1 2 3 5 8 13 21 34 55 89 >>> f <function fib at 10042ed0>
ฟังก์ชั่นในไพธอนจะคืนค่ากลับมาเสมอ ซึ่งปกติจะใช้ด้วยคำสั่ง return VALUE แต่ในตัวอย่างข้างต้นไม่มีการคืนค่าด้วยคำสั่ง return กรณีนี้ไพธอนจะคืนค่าเป็นค่าพิเศษคือ None
>>> print fib(0) None
จากตัวอย่างข้างต้น สามารถเขียนในรูปฟังก์ชั่นที่ส่งคืนค่าดังนี้
>>> def fib2(n): # return Fibonacci series up to ... """Return a list containing the Fibonacci series up to n."" ... result = [ ... a, b = 0, ... while b < n ... result.append(b) # see belo ... a, b = b, a+ ... return resul ... >>> f100 = fib2(100) # call i >>> f100 # write the result [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
ความรู้ใหม่
Noneresult.append(b) เป็นเมธอดของลิสต์ result เมธอดก็คือฟังก์ชั่นที่เป็นเฉพาะของออปเจคต์นั้น ซึ่งมีรูปแบบการเขียนเป็น obj.methodnameresult.append(b) มีผลเท่ากับ "result = result + [b]" แต่เขียนได้กระชับและเข้าใจง่ายกว่ามีหลักในการกำหนดค่าอาร์กิวเมนต์คือ
เป็นการกำหนดค่าปริยายให้กับอาร์กิวเมนต์ มีรูปแบบว่าอาร์กิวเมนต์ที่จะกำหนดค่าปริยายให้ จะต้องอยู่ทางขวาเสมอ ส่วนตัวที่ไม่กำหนด จะต้องอยู่ทางซ้ายเสมอ
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
while True:
ok = raw_input(prompt)
if ok in ('y', 'ye', 'yes'): return True
if ok in ('n', 'no', 'nop', 'nope'): return False
retries = retries - 1
if retries < 0: raise IOError, 'refusenik user'
print complaint
การใช้งานเช่น ask_ok('Do you really want to quit?')
หรือ ask_ok('OK to overwrite the file?', 2, 'Please answer y or n')
จากตัวอย่างหลัง retries คือ 2 และ complaint คือ 'Please answer y or n'
ในตัวอย่างนี้ มีคำใหม่คือ in เป็นการดูว่าตัวแปร ok อยู่ภายในช่วงที่กำหนดหรือไม่
ข้อควรระวัง
>>> i = 5 >>> def f(arg=i): ... print arg ... >>> f() 5 >>> i=6 >>> f() 5
>>> def f(a, L=[]): ... L.append(a) ... return L ... >>> print f(1) [1] >>> print f(2) [1, 2] >>> print f(3) [1, 2, 3]
วิธีแก้คือ ให้หลีกเลื่ยงข้อมูลชนิดนี้ในการกำหนดค่าปริยาย จากตัวอย่างจะดัดแปลงฟังก์ชั่นเป็น
def f(a, L=None):
if L is None:
L = []
L.append(a)
return Lเหมือนกับหัวข้อก่อนหน้า แต่ในหัวข้อนี้ เจาะจงอธิบายลักษณะที่กำหนดเป็นคีย์เวิร์ด มีรูปแบบคือ "keyword = value"
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print "-- This parrot wouldn't", action,
print "if you put", voltage, "volts through it."
print "-- Lovely plumage, the", type
print "-- It's", state, "!"การใช้งาน
parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')parrot() # ผิดเพราะขาดค่าที่ไม่มีค่าปริยาย คือ voltage parrot(voltage=5.0, 'dead') # ผิดเพราะค่าปริยายอยู่ซ้าย จริง ๆ ต้องอยู่ขวา parrot(110, voltage=220) # ผิดเพราะกำหนดค่าซ้อน parrot(actor='John Cleese') # ผิดเพราะชื่อไม่มีชื่อคีย์เวิร์ด actor
ตัวอย่างการรายงานข้อผิดพลาดของการกำหนดค่าซ้อน
>>> def function(a): ... pass ... >>> function(0, a=0) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: function() got multiple values for keyword argument 'a'
ตัวอย่างต่อไปจะแสดงให้เห็นประโยชน์ที่แท้จริงของหัวข้อนี้ คือ การระบุอาร์กิวเมนต์แบบให้ง่ายต่อการพลิกแพลง คือเราสามารถระบุอาร์กิวเมนต์แบบอ้างอิงได้ โดยมีรูปแบบคือ
def function_name(normal_parameter, *tuple_parameter, **dictionary_parameter)
ตัวอย่างคือ
def cheeseshop(kind, *arguments, **keywords):
print "-- Do you have any", kind, '?'
print "-- I'm sorry, we're all out of", kind
for arg in arguments: print arg
print '-'*40
keys = keywords.keys()
keys.sort()
for kw in keys: print kw, ':', keywords[kw]เรียกใช้ด้วยคำสั่ง
cheeseshop('Limburger', "It's very runny, sir.",
"It's really very, VERY runny, sir.",
client='John Cleese',
shopkeeper='Michael Palin',
sketch='Cheese Shop Sketch')ในที่นี้
kind = 'Limburger'arguments = ("It's very runny, sir.", "It's really very, VERY runny, sir.")keywords = { client:'John Cleese', shopkeeper:'Michael Palin', sketch:'Cheese Shop Sketch' }ผลลัพธ์คือ
-- Do you have any Limburger ? -- I'm sorry, we're all out of Limburger It's very runny, sir. It's really very, VERY runny, sir. ---------------------------------------- client : John Cleese shopkeeper : Michael Palin sketch : Cheese Shop Sketch
ความรู้ใหม่
จากตัวอย่างเรียกใช้เมธอด sort() ในการเรียงข้อมูลดัชนี ซึ่งเป็นเมธอดของลิสต์
ลิสต์นี้ได้มาจากการหาดัชนีของดิกชันนารี keyword ได้ออกมาเป็นลิสต์ชื่อ keys ด้วยเมธอดของดิกชันนารีคือ keys()
หากเราส่งผ่านอาร์กิวเมนต์แบบอ้างอิงซึ่งจะกลายเป็นทูเปิลแล้ว เราจะได้ความยืดหยุ่นในการกำหนดอาร์กิวเมนต์ ตัวอย่างคือ
>>> def testparm(x, *y):
... print 'x=',x,'y=',y
...
>>> testparm('a',1,2,3)
x= a y= (1, 2, 3)หรือ
>>> def testparm(x, *y):
... print 'x=', x, 'y=',
... for i in y:
... print i,
...
>>> testparm('a',1,2,3)
x= a y= 1 2 3ตัวอย่างในบทความต้นฉบับคือ
def fprintf(file, format, *args):
file.write(format % args)จากตัวอย่างก่อน ๆ ที่เรารู้เรื่องการผ่านค่าแบบอ้างอิงเป็นทูเปิลและดิกชันนารีแล้ว เราสามารถพลิกแพลงได้ เช่น
ในตัวอย่างนี้ใช้ลิสต์แทนทูเปิล (ถ้าไม่มีการเปลี่ยนแปลงค่า ลิสต์และทูเปิลสามารถใช้แทนกันได้แบบตรง ๆ )
>>> range(3, 6) # normal call with separate arguments [3, 4, 5] >>> args = [3, 6] >>> range(*args) # call with arguments unpacked from a list [3, 4, 5]
ตัวอย่างนี้เป็นดิกชันนารี
>>> def parrot(voltage, state='a stiff', action='voom'):
... print "-- This parrot wouldn't", action,
... print "if you put", voltage, "volts through it.",
... print "E's", state, "!"
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !ยืมความสามารถเรื่อง Functional Programming แบบภาษา Lisp มาใช้
โครงสร้างชวนเวียนหัวหน่อย ดูตัวอย่างดีกว่า
แบบไม่ใช้ lambda
>>> def f(x): ... return x*2 ... >>> f(3) 6
ใช้ lambda แบบแรก
>>> g = lambda x: x*2 >>> g(3) 6
ใช้ lambda แบบชั่วคราวจริง ๆ
>>> (lambda x: x*2)(3) 6
อีกตัวอย่างนึง ใช้ผสมกับฟังก์ชั่น
>>> def make_incrementor(n): ... return lambda x: x + n ... >>> f = make_incrementor(42) >>> f(0) 42 >>> f(1) 43
บรรทัดแรกถัดจากชื่อฟังก์ชั่น เป็นบรรทัดพิเศษที่ใส่บรรทัดข้อความอธิบายการทำงานของฟังก์ชั่น ถ้าใช้ตรีอัญประกาศ """ หรือ ''' ก็สามารถเขียนได้หลายบรรทัด
สามารถเรียกดูข้อความในบรรทัดนี้ได้จากเมธอด function_name.__doc__
ตัวอย่าง
>>> def my_function():
... """Do nothing, but document it.
...
... No, really, it doesn't do anything.
... """
... pass
...
>>> print my_function.__doc__
Do nothing, but document it.
No, really, it doesn't do anything. 5.1 ลิสต์อีกที (More on Lists)
5.2 ประโยค del (The del statement)
5.3 ทูเปิล (Tuples and Sequences)
5.4 เซ็ต (Sets)
5.5 ดิกชันนารี (Dictionaries)
5.6 เทคนิกการวนรอบ (Looping Techniques)
5.7 เงื่อนไข (More on Conditions)
5.8 น้ำหนักของข้อมูลแบบลำดับ (Comparing Sequences and Other Types)
บทนี้จะอธิบายเทคนิกการใช้งานข้อมูล
เวลาใช้งานจริง เราจะใช้ลิสต์มากหน่อย เพราะมันเปลี่ยนแปลงค่าได้ เลยทำให้มีเมธอดของลิสต์เยอะหน่อย
append(<em>x</em>)a[len(a):] = [<em>x</em>]
>>> a=[1,2,3] >>> a.append(4) >>> a [1, 2, 3, 4]
extend(<em>L</em>)a[len(a):] = <em>L</em>
>>> a=[1,2,3] >>> L=[4,5,6] >>> a.extend(L) >>> a [1, 2, 3, 4, 5, 6]
insert(<em>i</em>, <em>x</em>)a.insert(0, x) ก็คือการไปแทรกข้างหน้าa.insert(len(a), x) ก็คือการไปต่อท้าย คือ a.append(x)>>> a=[1,2,3] >>> a.insert(2,0) >>> a [1, 2, 0, 3]
remove(<em>x</em>)>>> a=[1,2,3] >>> a.remove(2) >>> a [1, 3] >>> a.remove(2) Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: list.remove(x): x not in list
pop(<em>[i]</em>)>>> a=[1,2,3] >>> a.pop(1) 2 >>> a [1, 3]
index(<em>x</em>)>>> a=[1,2,3] >>> a.index(2) 1
count(<em>x</em>)>>> a=[2,2,2,9,4,4,4,4] >>> a.count(2) 3
sort()>>> a=[1,5,4,2,3] >>> a.sort() >>> a [1, 2, 3, 4, 5]
reverse()>>> a=[1,5,4,2,3] >>> a.reverse() >>> a [3, 2, 4, 5, 1]
ตัวอย่างรวมอีกทีนึง
>>> a = [66.25, 333, 333, 1, 1234.5]
>>> print a.count(333), a.count(66.25), a.count('x')
2 1 0
>>> a.insert(2, -1)
>>> a.append(333)
>>> a
[66.25, 333, -1, 333, 1, 1234.5, 333]
>>> a.index(333)
1
>>> a.remove(333)
>>> a
[66.25, -1, 333, 1, 1234.5, 333]
>>> a.reverse()
>>> a
[333, 1234.5, 1, 333, -1, 66.25]
>>> a.sort()
>>> a
[-1, 1, 66.25, 333, 333, 1234.5]ถ้าจะใช้งานลิสต์แบบสแต็คคือ เข้าก่อนออกหลัง ก็แค่ใช้เมธอดให้เหมาะสม คือเติมด้วย append() แล้วเอาออกด้วย pop()
>>> stack = [3, 4, 5] >>> stack.append(6) >>> stack.append(7) >>> stack [3, 4, 5, 6, 7] >>> stack.pop() 7 >>> stack [3, 4, 5, 6] >>> stack.pop() 6 >>> stack.pop() 5 >>> stack [3, 4]
คือ เข้าก่อนออกก่อน ก็ใช้ append() และ pop(0) ตามลำดับ
>>> queue = ["Eric", "John", "Michael"]
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.pop(0)
'Eric'
>>> queue.pop(0)
'John'
>>> queue
['Michael', 'Terry', 'Graham']มี 3 ตัว (ไม่นับคำสั่ง lambda)
<strong>filter(<em>function</em>, <em>sequence</em>)</strong>sequence เฉพาะถ้า function คืนค่าที่เป็นจริง (ไม่ใช่ศูนย์หรือ None) งงนิดหน่อย ดูตัวอย่างดีกว่า เป็นการหาจำนวนเฉพาะ
>>> def f(x): return x % 2 != 0 and x % 3 != 0 ... >>> filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 23]
<strong>map(<em>function</em>, <em>sequence</em>)</strong>sequence ไปทำงานใน function แล้วคืนช่วงของผลลัพธ์ออกมาเป็นลิสต์
>>> def cube(x): return x*x*x ... >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
หาก function ต้องการอาร์กิวเมนต์มากกว่าหนึ่งตัว ก็ต้องใส่ sequence ด้วยจำนวนที่เท่ากัน
>>> seq = range(8) >>> def add(x, y): return x+y ... >>> map(add, seq, seq) [0, 2, 4, 6, 8, 10, 12, 14] >>> s2 = range(10,18) >>> map(add, seq, s2) [10, 12, 14, 16, 18, 20, 22, 24] >>> s3 = range(18, 10, -1) >>> map(add, seq, s3) [18, 18, 18, 18, 18, 18, 18, 18]
<strong>reduce(<em>function</em>, <em>sequence</em>)</strong>sequence ชุดแรก ไปเป็นข้อมูลนำเข้าให้ function กับ sequence ชุดต่อ ๆ ไป จนหมดข้อมูล
>>> def add(x,y): return x+y ... >>> reduce(add, range(1, 11)) 55
ถ้าไม่มีข้อมูลจาก sequence จะแสดงข้อผิดพลาด
>>> reduce(add, range(0)) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: reduce() of empty sequence with no initial value
เพื่อเป็นการป้องการการผิดพลาดดังกล่าว อาจใส่อาร์กิวเมนต์ตัวที่สามซึ่งจะกลายเป็นค่าเริ่มต้นให้กับ function เพื่อป้องกันกรณีลิสต์ว่าง ดังนี้
>>> def xsum(seq): ... def add(x,y): return x+y ... return reduce(add, seq, 0) ... >>> xsum(range(1, 11)) 55 >>> xsum([]) 0
เป็นโครงสร้างเฉพาะตัวของไพธอนที่ยืมมาจากภาษา Haskell/ML ในการสร้างลิสต์ใหม่จากลิสต์ที่มีอยู่ ใช้มากในไพธอน มีรูปแบบเป็น
[f(x) for x in L [ if p(x) ] ]
แปลว่า ให้สร้างลิสต์ด้วยฟังก์ชั่น f จากลิสต์ L สมาชิกต่อสมาชิก โดยแต่ละสมาชิกจะต้องมีค่า p(x) ที่เป็นจริง
โครงสร้างส่วนหลัง ตรงที่เป็น if ... เป็นตัวเลือก อาจใส่หรือไม่ก็ได้
ตัวอย่าง
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
>>> vec = [2, 4, 6]
>>> [3*x for x in vec]
[6, 12, 18]
>>> [3*x for x in vec if x > 3]
[12, 18]
>>> [3*x for x in vec if x < 2]
[]
>>> [[x,x**2] for x in vec]
[[2, 4], [4, 16], [6, 36]]
>>> [x, x**2 for x in vec] # error - parens required for tuples
File "<stdin>", line 1, in ?
[x, x**2 for x in vec]
^
SyntaxError: invalid syntax
>>> [(x, x**2) for x in vec]
[(2, 4), (4, 16), (6, 36)]
>>> vec1 = [2, 4, 6]
>>> vec2 = [4, 3, -9]
>>> [x*y for x in vec1 for y in vec2]
[8, 6, -18, 16, 12, -36, 24, 18, -54]
>>> [x+y for x in vec1 for y in vec2]
[6, 5, -7, 8, 7, -5, 10, 9, -3]
>>> [vec1[i]*vec2[i] for i in range(len(vec1))]
[8, 12, -54]
>>> [str(round(355/113.0, i)) for i in range(1,6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']del (The del statement)ใช้งานคล้าย ๆ pop() แต่เลือกช่วงได้ด้วย จึงต้องระบุดัชนีเสมอ
>>> a = [-1, 1, 66.25, 333, 333, 1234.5] >>> del a[0] >>> a [1, 66.25, 333, 333, 1234.5] >>> del a[2:4] >>> a [1, 66.25, 1234.5] >>> del a[:] >>> a []
สามารถใช้ del ในการลบตัวแปรได้ด้วย
>>> del a
ทูเปิลคล้ายกับลิสต์ ต่างกันตรงเป็นข้อมูลที่สามารถกำหนดค่าได้ครั้งเดียว จึงเหมาะที่จะใช้ในงานที่ต้องการค่าคงที่
ลิสต์ใช้วงเล็บก้ามปู [] แต่ทูเปิลใช้วงเล็บธรรมดา () หรืออาจละเลยไม่ใส่ก็ได้ โดยใส่แค่จุลภาค , ตามหลังสมาชิก (แต่ต้องระวังตัวเองงงเอง)
>>> t = 12345, 54321, 'hello!' >>> t[0] 12345 >>> t (12345, 54321, 'hello!') >>> # Tuples may be nested: ... u = t, (1, 2, 3, 4, 5) >>> u ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
ตัวอย่างการละเลยการใส่วงเล็บ ซึ่งถ้าดูผ่าน ๆ อาจสับสนได้
>>> empty = ()
>>> singleton = 'hello', # <-- note trailing comma
>>> len(empty)
0
>>> len(singleton) # ได้ค่าเป็น 1 เพราะเป็นทูเปิลที่มีสมาชิก 1 ตัว
1
>>> singleton
('hello',)การละเลยการใส่วงเล็บในตอนกำหนดค่า ไพธอนเรียกว่า การอัดข้อมูลเป็นอนุกรม (sequence packing) ในกรณีนี้คือ tuple packing (ถ้าละเลยการใส่วงเล็บแล้ว จะถือว่าเป็นข้อมูล tuple เสมอ)
t = x, y, z
และยังสามารถกำหนดค่าแบบย้อนกลับได้ อันนี้เรียกว่า การแตกข้อมูลอนุกรม (sequence unpacking)
x, y, z = t
(ซึ่งถ้าเขียนให้ถูกจริง ๆ แล้วคือ (x, y, z) = t)
และแน่นอนว่าใช้กับลิสต์ได้เช่นเดียวกัน
[x, y, z] = t
ไพธอนรุ่นหลัง เติมความสามารถเรื่องเซ็ตเข้าไป ซึ่งเซ็ตก็คือลิสต์ที่สามารถใช้งานในลักษณะเซ็ตได้ เช่น การทำยูเนียนและอินเตอร์เซคเป็นต้น
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> fruit = set(basket) # create a set without duplicates
>>> fruit
set(['orange', 'pear', 'apple', 'banana'])
>>> 'orange' in fruit # fast membership testing
True
>>> 'crabgrass' in fruit
False
>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
set(['a', 'r', 'b', 'c', 'd'])
>>> a - b # letters in a but not in b
set(['r', 'd', 'b'])
>>> a | b # letters in either a or b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b # letters in both a and b
set(['a', 'c'])
>>> a ^ b # letters in a or b but not both
set(['r', 'd', 'b', 'm', 'z', 'l'])เป็นชนิดข้อมูลพิเศษที่อยู่ในรูป {<em>key</em>: <em>value</em>, ...}
key อาจเป็นข้อมูลชนิดสคริง ตัวเลข หรือทูเปิลที่ไม่ได้บรรจุ multable object ไว้delkeys() ในการแสดงค่าคีย์ทั้งหมด และใช้เมธอด has_key() ในการค้นค่าคีย์>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> tel.keys()
['guido', 'irv', 'jack']
>>> tel.has_key('guido')
True
>>> 'guido' in tel
True
แปลงทูเปิลในลิสต์มาเป็นดิกชันนารีด้วยฟังก์ชั่น dict()
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}
>>> dict([(x, x**2) for x in (2, 4, 6)]) # use a list comprehension
{2: 4, 4: 16, 6: 36}หรือหากค่าคีย์เป็นสตริงล้วน อาจกำหนดค่าแบบนี้ก็ได้ (เลียนแบบการส่งผ่านค่าไปยังฟังก์ชั่น)
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}iteritems()>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.iteritems():
... print k, v
...
gallahad the pure
robin the braveenumerate()>>> for i, v in enumerate(['tic', 'tac', 'toe']): ... print i, v ... 0 tic 1 tac 2 toe
zip()>>> questions = ['name', 'quest', 'favorite color'] >>> answers = ['lancelot', 'the holy grail', 'blue'] >>> for q, a in zip(questions, answers): ... print 'What is your %s? It is %s.' % (q, a) ... What is your name? It is lancelot. What is your quest? It is the holy grail. What is your favorite color? It is blue.
reversed()>>> for i in reversed(xrange(1,10,2)): ... print i ... 9 7 5 3 1
sorted()>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] >>> for f in sorted(set(basket)): ... print f ... apple banana orange pear
while และ if ไม่จำเป็นต้องเป็นการเปรียบเทียบค่าเสมอไป แต่จะเป็นอะไรก็ได้ที่ ถ้าคืนค่าที่ไม่เป็นศุนย์หรือ None จะถูกนับว่าเป็นจริงin และ not in ใช้ดูว่ามีค่าอยู่ในลำดับข้อมูลหรือเปล่าis และ is not ใช้ดูว่าเป็นออปเจคต์เดียวกันหรือเปล่าa < b == c>>> True == 1 True >>> 1 < 2 == 1 False >>> 1 < 2 == 2 True
not สำคัญที่สุด และ or สำคัญน้อยที่สุด คือA and not B or C เขียนได้เป็น (A and (not B)) or C>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance' >>> non_null = string1 or string2 or string3 >>> non_null 'Trondheim
(1, 2, 3) < (1, 2, 4)
[1, 2, 3] < [1, 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python'
(1, 2, 3, 4) < (1, 2, 4)
(1, 2) < (1, 2, -1)
(1, 2, 3) == (1.0, 2.0, 3.0)
(1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4) 6.1 เพิ่มเติม (More on Modules)
6.2 โมดูลมาตรฐาน (Standard Modules)
6.3 ฟังก์ชั่น dir() (The dir() Function)
6.4 แพกเกจ (Packages)
ธรรมชาติของการเขียนโปรแกรมแบบมือใหม่ (มือเก่าจะวางโครงสร้างก่อน) ก็คือหัดเขียนในแบบโต้ตอบก่อน ตามมาด้วยลงไฟล์จริง พอไฟล์ใหญ่ขึ้นก็ต้องอาศัยโมดูลเพื่อเอาไว้เก็บพวกฟังก์ชั่นที่ต้องเรียกใช้ซ้ำ ๆ กัน พูดง่าย ๆ คือโมดูลคือที่เก็บฟังก์ชั่นเพื่อให้เรียกใช้สะดวก
ใช้ประโยค import module_name ในการเรียกใช้
ส่วนชื่อโมดูลจะถูกเก็บไว้ในตัวแปรรวม (เฉพาะในโมดูล) ชื่อ __name__
สมมุติเราสร้างโมดูลเป็นไฟล์ชื่อ fibo.py (ให้อยู่ในไดเรคทอรี่ปัจจุบัน) มีเนื้อไฟล์ว่า
# Fibonacci numbers module
def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while b < n:
print b,
a, b = b, a+b
def fib2(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
while b < n:
result.append(b)
a, b = b, a+b
return resultเริ่มต้นใช้งานว่า
>>> import fibo
เรียกใช้งานฟังก์ชั่นโดย
>>> fibo.fib(1000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 >>> fibo.fib2(100) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] >>> fibo.__name__ 'fibo'
เพื่อให้กระชับ เราสามารถกำหนดค่าตัวแปรแทนเมธอดในโมดูลได้
>>> fib = fibo.fib >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377
modname.itername จึงไม่ต้องกังวลเรื่องชื่อตัวแปรในโมดูลจะซ้ำกับตัวแปรในโปรแกรมหลัก>>> from fibo import fib, fib2 >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377
'_' ) แบบละเลยชื่อโมดูล>>> from fibo import * >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377
PYTHONPATH/usr/lib/python2.4 (ตัวเลข 2.4 จะเปลี่ยนไปตามรุ่นไพธอนที่ใช้)
การค้นพาธที่ว่า สามารถดูได้จากตัวแปร sys.path ในไพธอน ซึ่งในทางปฏิบัติเราสามารถแก้ไขได้จากในโปรแกรม ทำให้การเขียนโปรแกรมมีความยืดหยุ่น
ไพธอนเร่งความเร็วตอนเริ่มระบบด้วยการแปล (compile) เช่นถ้าเรามีไฟล์ชื่อ spam.py ถ้าไฟล์นี้ถูกอิมพอร์ต ไพธอนจะคอมไพล์แล้วเก็บในชื่อ spam.pyc ซึ่งไฟล์นี้จะไม่ขึ้นกับระบบปฏิบัติการ หมายความว่าเราสามารถคัดลอกไฟล์นามสกุล .pyc ไปใช้กับเครื่องต่างระบบได้เลย
สำหรับเซียน
-O ไพธอนจะคอมไพล์ไฟล์ให้เล็ก โดยนามสกุลจะกลายเป็น .pyo แทน-OO มีผลเหมือนอันแรกแต่จะลบข้อมูลที่เป็น docstring ออก.pyc หรือ .pyo อยุ่แล้ว ไม่จำเป็นต้องมีไฟล์ต้นฉบับ (นิยมนามสกุลเป็น .py) ดังนั้นหากไม่ต้องการแพร่ซอร์สโค๊ด อาจจ่ายเป็นไฟล์คอมไพล์เหล่านี้แทนไพธอนมีโมดูลมาตรฐานเยอะมาก ดูได้จาก บรรณสารของไพธอน (Python Library Reference) โมดูลหลายตัวเป็นโมดูลของระบบ บางตัวอาจเรียกใช้ได้ในบางสถานะ
ตัวอย่างเช่น โมดูล sys ซึ่งเป็นโมดูลระบบ
sys.ps1 จะเก็บข้อความที่เป็นพร้อมต์หลัก (Primary prompt) และ sys.ps2 จะเก็บพร้อมต์ตาม (Secondary prompt) ตัวแปรทั้งสองจะเรียกใช้ได้ในหมวดโต้ตอบเท่านั้น>>> import sys >>> sys.ps1 '>>> ' >>> sys.ps2 '... ' >>> sys.ps1 = 'C> ' C> print 'Yuck!' Yuck! C>
sys.path เก็บพาธการค้นหาของระบบในรูปของลิสต์ ดังนั้นเราอาจเพิ่มพาธการค้น ได้โดยการเพิ่มหรือเปลียนค่า>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')dir() (The dir() Function)ฟังก์ชั่น dir() ใช้ดูว่าโมดูลนั้นประกอบไปด้วยรายชือ (คือตัวแปร โมดูล ฟังก์ชั่น คลาส หรืออะไรก็ตามที่เราสร้างไว้) อะไรบ้าง เก็บค่าเป็นลิสต์
>>> import fibo, sys >>> dir(fibo) ['__name__', 'fib', 'fib2'] >>> dir(sys) ['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', '__stdin__', '__stdout__', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder', 'callstats', 'copyright', 'displayhook', 'exc_clear', 'exc_info', 'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'getdefaultencoding', 'getdlopenflags', 'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'version', 'version_info', 'warnoptions']
ใช้ dir() เฉย ๆ จะดูรายชื่อในสภาพแวดล้อมของปัจจุบัน
>>> a = [1, 2, 3, 4, 5] >>> import fibo >>> fib = fibo.fib >>> dir() ['__builtins__', '__doc__', '__file__', '__name__', 'a', 'fib', 'fibo', 'sys']
เพื่อไม่ให้รกรุงรัง dir() จึงไม่ยอมดูฟังก์ชั่นบิลด์อิน (build-in function) ของไพธอนให้ แต่ถ้าเราอยากดู ต้องเรียกผ่านโมดูล __builtin__
>>> import __builtin__ >>> dir(__builtin__) ['ArithmeticError', 'AssertionError', 'AttributeError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'IOError', 'ImportError', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', '__name__', 'abs', 'apply', 'basestring', 'bool', 'buffer', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']
เวลามีโมดูลที่เราสร้างขึ้นเยอะ เราจะจัดกลุ่มให้ไปรวมในไดเรคทอรี่ต่างหาก (ทำเหมือนเวลาเรามีไฟล์เยอะ ๆ แล้วเราจะจัดระเบียบไฟล์ ในระบบไฟล์เรียงไดเรคทอรี่ด้วย / เช่น dira/dirb แต่ไพธอนเรียงด้วย . เช่น pa.pb) ไพธอนเรียกวิธีจัดการกลุ่มโมดูลนี้ว่า แพกเกจ ซึ่งชื่อแพกเกจก็คือชื่อไดเรคทอรี่นั่นเอง
สมมุติว่าเราสร้างโมดูลที่ใช้จัดการเสียง(เพลง)ขึ้นมาโมดูลหนึ่ง การทำงานมีทั้ง การจัดการรูปแบบไฟล์เสียง มีทั้งการปรุงแต่งเสียง และมีทั้งการกรองเสียง ซึ่งต้องอาศัยการทำงานที่ต่างกัน เราควรเขียนโค๊ดแยกแต่ละการจัดการออกจากกัน และจัดรวมเป็นแพกเกจ แพกเกจเราจะมีโครงสร้างดังนี้
Sound/ Top-level package
__init__.py Initialize the sound package
Formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
Effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
Filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...พอแพกเกจเราถูกอิมพอร์ต ไพธอนก็จะค้นพาธจาก sys.path พอพบแล้วก็จัดการคอมไพล์เพื่อจะถูกเรียกใช้ต่อไป
ไฟล์ __init__.py ใช้บอกไพธอนว่า ในไดเรคทอรี่นี้เป็นแพกเกจ ซึ่งไฟล์นี้อาจเป็นไฟล์เปล่า ๆ ก็ได้ หรืออาจบรรจุโค๊ดที่ใช้เริ่มงานแพกเกจ หรืออาจใส่ค่าตัวแปร __all__ ที่จะใช้บอกว่าแพกเกจนี้จะต้องโหลดโมดูลไหนบ้าง
เวลาเรียกใช้ เราอาจเลือกเรียกเฉพาะโมดูลที่ต้องการก็ได้ ไม่จำเป็นต้องเรียกทั้งหมด
เรียกใช้ได้สองแบบ
import ... [ as ... ]import Sound.Effects.echo
เวลาอ้างถึงต้องอ้างแบบเต็ม ๆ
Sound.Effects.echo.echofilter(input, output, delay=0.7, atten=4)
import Sound.Effects.echo as SEe
อ้างถึงโดยใช้ชื่อย่อ
SEe.echofilter(input, output, delay=0.7, atten=4)
from ... import ...from Sound.Effects import echo
เวลาเรียกใช้ เรียกเฉพาะชื่อ โมดูล.ฟังก์ชั่น ที่เราอิมพอร์ตเข้ามา
echo.echofilter(input, output, delay=0.7, atten=4)
หรือถ้าอิมพอร์ตเจาะเฉพาะฟังก์ชั่น ก็เรียกเฉพาะฟังก์ชั่น
from Sound.Effects.echo import echofilter echofilter(input, output, delay=0.7, atten=4)
หมายเหตุ
ImportErrorเวลาถูกเรียกอิมพอร์ต ไพธอนใช้ตัวแปร __all__ ในไฟล์ __init__.py สำหรับระบุว่าในแพกเกจนี้จะต้องเรียกใช้งานโมดูลไหนบ้าง (แทนการดูจากชื่อไฟล์ในไดเรคทอรี่ เพราะมีข้อจำกัดมากสำหรับระบบปฏิบัติการที่หลากลาย)
เช่น ในไฟล์ Sounds/Effects/__init__.py อาจมีเนื้อไฟล์เป็น
__all__ = ["echo", "surround", "reverse"]
นั่นคือเมื่อไพธอนพบคำสั่งว่า from Sound.Effects import * เขาจะอิมพอร์ตโมดูลทั้งสามตัวเข้ามา
แต่ถ้าเราไม่ได้กำหนดค่าให้กับ __all__ เวลาไพธอนพบคำสั่ง from Sound.Effects import * เขาจะเพียงแค่รันไฟล์ __init__.py และรับรู้ว่ามีโมดูลอะไรในแพกเกจบ้างเท่านั้น (ไม่ได้คอมไพล์และอิมพอร์ตโมดูลเข้ามาในห้วงการทำงาน-namespace เพื่อเตรียมพร้อมจริง ๆ )
หากใช้ในรูปแบบของ from package import module ควรระวังเรื่องชื่อโมดูลหรือฟังก์ชั่นซ้ำ อาจทำให้เรียกใช้ผิด
มีหลักอยู่ว่า
surround สามารถเรียกใช้โมดูล echo ได้โดยตรง
import echo echo.echofilter(input, output, delay=0.7, atten=4)
หรือ
from echo import echofilter echofilter(input, output, delay=0.7, atten=4)
from . import echo from .. import Formats from ..Filters import equalizer
ต้องใส่ชื่อไดเรคทอรี่ที่บรรจุโมดูลย่อยไว้ในตัวแปรพิเศษชื่อ __path__ ซึ่งเป็นลิสต์ เก็บค่าพาธของโมดูลย่อยไว้
7.1 การจัดรูปแบบเอาต์พุต (Fancier Output Formatting)
7.2 การอ่านเขียนไฟล์ (Reading and Writing Files)
สามารถจัดรูปแบบได้สองแบบหลัก คือใช้ฟังก์ชั่น และใช้ตัวกระทำ %
ตัวอย่างการใช้ฟังก์ชั่นแปลงเป็นตัวอักขระ str() ซึ่งให้คนอ่านง่าย หรือแปลงแบบดิบ repr() คือให้ระบบอ่านง่าย (สามารถเขียนอีกแบบภายใต้เครื่องหมาย ``)
>>> s = 'Hello, world.'
>>> str(s)
'Hello, world.'
>>> repr(s)
"'Hello, world.'"
>>> str(0.1)
'0.1'
>>> repr(0.1)
'0.10000000000000001'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'
>>> print s
The value of x is 32.5, and y is 40000...
>>> # The repr() of a string adds string quotes and backslashes:
... hello = 'hello, world\n'
>>> hellos = repr(hello)
>>> print hellos
'hello, world\n'
>>> # The argument to repr() may be any Python object:
... repr((x, y, ('spam', 'eggs')))
"(32.5, 40000, ('spam', 'eggs'))"
>>> # reverse quotes are convenient in interactive sessions:
... `x, y, ('spam', 'eggs')`
"(32.5, 40000, ('spam', 'eggs'))"
ตัวอย่างการใช้ฟังก์ชั่น repr() ร่วมกับเมธอดจัดชิดขวาของสตริง rjust() เทียบกับการใช้ตัวกระทำจัดรูปแบบ %
>>> for x in range(1, 11): ... print repr(x).rjust(2), repr(x*x).rjust(3), ... # Note trailing comma on previous line ... print repr(x*x*x).rjust(4) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000 >>> for x in range(1,11): ... print '%2d %3d %4d' % (x, x*x, x*x*x) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000
ลองดูเมธอด zfill() บ้าง
>>> '12'.zfill(5) '00012' >>> '-3.14'.zfill(7) '-003.14' >>> '3.14159265359'.zfill(5) '3.14159265359'
เทียบกับการใช้ %
>>> import math >>> print 'The value of PI is approximately %5.3f.' % math.pi The value of PI is approximately 3.142.
อีกอันนึงเป็นการจัดชิดขอบซ้ายขวาด้วย %
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
... print '%-10s ==> %10d' % (name, phone)
...
Jack ==> 4098
Dcab ==> 7678
Sjoerd ==> 4127
พิเศษนิดนึงสำหรับตัวจัดรูปสตริง %s คือถ้าข้อมูลไม่อยู่ในรูปสตริง เขาจะแปลงอัตโนมัติด้วยฟังก์ชั่น str()
>>> print "%s %s %s" % (1, True, None) 1 True None
พิเศษกว่านั้น ถ้าข้อมูลเป็นดิกชันนารี ยังใช้รูปแบบ %(<em>name</em>)<em>format</em> ได้อีกด้วย
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print 'Jack: %(Jack)d; Sjoerd: %(Sjoerd)d; Dcab: %(Dcab)d' % table
Jack: 4098; Sjoerd: 4127; Dcab: 8637678เปิดไฟล์ด้วยฟังก์ชั่น open(<em>filename</em>, <em>mode</em>) ได้ค่าเป็น ไฟล์ออปเจกต์
>>> f=open('/tmp/workfile', 'w')
>>> print f
<open file '/tmp/workfile', mode 'w' at 80a0960>mode เป็นได้ดังนี้
'r' อ่านอย่างเดียว ตัวนี้เป็นค่าปริยาย'w' เขียนอย่างเดียว ถ้ามีเนื้อเก่าจะถูกทับหมด'a' เติมอย่างเดียว คือเขียนต่อที่ท้ายไฟล์'r+' ทั้งอ่านและเขียน (ใช้ร่วมกับเมธอด seek() ในการเลื่อนตำแหน่งอ่านเขียน)สำหรับเครื่องวินโดวส์และแมคอินทอช จะมีการเปิดแบบไบนารีด้วย ดังนั้นจะมีโหมดเพิ่มคือ 'rb' 'wb' และ 'r+b'
การจัดการไฟล์ระหว่างการเปิดแบบอักขระกับการเปิดแบบไบนารีคือ ในการเปิดแบบอักขระ ระบบจะเติมการจบบรรทัดด้วยอักขระพิเศษเพิ่มเข้าไป ทำให้เกิดปัญหาถ้าไฟล์นั้นเป็นไบนารีไฟล์
<strong><em>f</em>.read(<em>[ size ]</em>)</strong>>>> f.read() 'This is the entire file.\n' >>> f.read() ''
<strong><em>f</em>.readline()</strong>\n ถ้าอ่านไฟล์จนหมดแล้ว จะคืนค่าเป็นอักขระว่าง ("")
>>> f.readline() 'This is the first line of the file.\n' >>> f.readline() 'Second line of the file\n' >>> f.readline() ''
<strong><em>f</em>.readlines()</strong>>>> f.readlines() ['This is the first line of the file.\n', 'Second line of the file\n']
<strong>for <em>line</em> in <em>f</em>:</strong>>>> for line in f:
print line,
This is the first line of the file.
Second line of the file<strong><em>f</em>.write(<em>string</em>)</strong>None
>>> f.write('This is a test\n')ถ้าข้อมูลไม่ได้อยู่ในรูปสตริง ต้องแปลงก่อน
>>> value = ('the answer', 42)
>>> s = str(value)
>>