φυβλαςのβλογ
phyblas的博客



ความแตกต่างระหว่าง python 2.x และ 3.x
เขียนเมื่อ 2015/12/17 19:00
แก้ไขล่าสุด 2021/09/28 16:42
ตั้งแต่ไพธอน 3 ถูกปล่อยออกมาในปี 2008 ก็มีเสียงวิพากย์วิจารณ์มากมายว่ามีความแตกต่างไปจากไพธอน 2 มากเกินไปจนทำให้สูญเสียความเข้ากันได้

โค้ดที่เขียนด้วยไพธอน 2 ไม่สามารถนำมาใช้ในไพธอน 3 ได้โดยไม่มีการปรับแก้ ด้วยเหตุนี้จึงมีคนมากมายยังคงนิยมใช้ไพธอน 2 ต่อไปโดยไม่เคยคิดจะเปลี่ยนมาใช้ไพธอน 3

แม้ว่าคนที่เพิ่งมาศึกษาภาษาไพธอนเอาช่วงหลังๆมานี้มักจะได้รับคำแนะนำให้ศึกษาไพธอน 3 มากกว่า แต่ถึงอย่างนั้นไพธอน 2 ก็ยังเป็นที่นิยมมากกว่าอยู่ ดังนั้นจึงจำเป็นต้องเรียนรู้ไว้บ้าง

หากทำความเข้าใจเรื่องความแตกต่างระหว่างไพธอน 2 และ 3 ได้แล้ว ไม่ว่าจะเริ่มศึกษาจากเวอร์ชันไหนก็สามารถเปลี่ยนไปใช้อีกเวอร์ชันได้ไม่ยากเย็น

- การตั้งชื่อตัวแปร
- ชนิดข้อมูลจำนวนเต็ม
- การใช้เลขนอกเหนือจากเลขฮินดูอารบิกเป็นค่าตัวเลข
- ฟังก์ชัน print
- ฟังก์ชัน input
- การหารจำนวนเต็ม
- การยกกำลังจำนวนติดลบ
- ชนิดข้อมูลของสายอักขระ
- ชนิดข้อมูลของ range
- การจัดการกับตัวแปรที่ใช้ใน for
- เมธอด keys, values และ items ของดิกชันนารี
- ฟังก์ชัน map, filter และ zip
- การใช้ฟังก์ชัน super
- ออบเจ็กต์ของความผิดพลาดในโครงสร้าง try except
- เมธอด next กับ __next__
- มอดูล __future__



การตั้งชื่อตัวแปร
ในไพธอน 2 ชื่อตัวแปรจะใช้ได้แค่อักษรโรมัน ๒๖ ตัวหลัก (ทั้งพิมพ์ใหญ่และพิมพ์เล็ก) และตัวเลข 0 ถึง 9 แล้วก็สัญลักษณ์ขีดล่าง _

แต่ในไพธอน 3 สามารถตั้งชื่อเป็นอักษรชนิดอื่นได้ เช่น
- อักษรโรมันที่มีสัญลักษณ์เพิ่มเติม (áéíóúýäëïöüÿøåæñ ฯลฯ)
- อักษรกรีก (αβγδεζηθικλμνξοπρστυφχψω ฯลฯ)
- อักษรไทย ลาว เขมร เวียดนาม จีน ญี่ปุ่น เกาหลี ฯลฯ (ไทย ລາວ ខ្មែរ Việt 漢字 カタカナ ひらがな 한글 ฯลฯ)
- และอื่นๆอีกมากมาย

การที่สามารถตั้งชื่อตัวแปรได้หลากหลายขึ้นก็อาจช่วยให้การใช้งานยืดหยุ่นขึ้นได้ดี

ตัวอย่าง ลองพิมพ์
จำนวนจังหวัดทั้งหมดในประเทศไทย = 77

ในไพธอน 3 จะไม่มีอะไรเกิดขึ้น ข้อความยาวๆนี้ได้รับการยอมรับให้เป็นชื่อตัวแปร และเก็บค่าตัวเลขไปเรียบร้อย แต่ในไพธอน 2 จะขึ้นว่า
SyntaxError: invalid syntax



ชนิดข้อมูลจำนวนเต็ม
ในไพธอน 2 นั้นจำนวนเต็มถูกแบ่งเป็น ๒ ชนิดคือ int กับ long แต่ในไพธอน 3 ได้รวมกันเป็นชนิดเดียวคือ int
โดยค่า int จะมีขอบเขตจำกัดอยู่ค่าหนึ่ง

ค่าสูงสุดของ int นั้นมีจำกัดอยู่แล้วแต่เครื่องโดยอาจจะเป็น 2 ยกกำลัง 63 ลบ 1 หรือ 2 ยกกำลัง 31 ลบ 1

ลองพิมพ์
import sys
print(sys.maxint)
ก็จะได้ค่าสูงสุดของ int ออกมา

ลองพิมพ์ลงในเชลโต้ตอบไปตามนี้
2**80
ในไพธอน 3 จะได้ผลลัพธ์เป็น
1208925819614629174706176

แต่ในไพธอน 2 จะได้ผลลัพธ์เป็น
1208925819614629174706176L

สิ่งที่ต่างกันคือในไพธอน 2 มีตัว L โผล่เพิ่มขึ้นมา ซึ่งตัว L ในที่นี้เป็นตัวบ่งบอกว่าเป็นข้อมูลชนิด long นั่นเอง

หมายความว่าในไพธอน 2 ถ้าหากใส่เลขที่ใหญ่เกินขอบเขตที่จะเป็น int ได้ก็จะถูกเก็บในรูปของ long

ในขณะที่ในไพธอน 3 จะใหญ่แค่ไหนก็ยังเป็น int อยู่ดี และจะไม่มีข้อมูลชนิด long

ดังนั้นหากพิมพ์ 1208925819614629174706176L ลงในไพธอน 3 ก็จะขึ้นว่า
SyntaxError: invalid syntax



การใช้เลขนอกเหนือจากเลขฮินดูอารบิกเป็นค่าตัวเลข
ในไพธอน 2 นั้นหากจะแปลงสายอักขระที่เก็บตัวเลขให้เป็นข้อมูลชนิดจำนวนตัวเลขจะต้องใช้เลขฮินดูอารบิกเท่านั้น เช่น
int('12') # ได้ 12

แต่ในไพธอน 3 อาจใช้เลขไทยหรือเลขอื่นๆได้อีกหลายชนิด หรืออาจใช้ปนกันก็ได้ เช่น
int('๑๒') # ได้ 12
float('๑๒.๒') # ได้ 12.2
float('๑2.๒2') # ได้ 12.22

เพียงแต่ว่ายังไงก็จำเป็นต้องเขียนเป็นสายอักขระแล้วแปลงเป็นตัวเลขอีกที ไม่สามารถนำมาคำนวณโดยตรง เช่น
๑+๑
ได้
SyntaxError: invalid character in identifier
ต้องเขียนเป็น
int('๑')+int('๑') # ได้ 2

นอกจากเลขไทยแล้วยังใช้ตัวเลขของภาษาอื่นได้อีกหลายชนิด เช่น ลาว เขมร พม่า เพียงแต่ว่าเลขจีนไม่สามารถใช้ได้
นี่ก็ถือเป็นรายละเอียดปลีกย่อยเล็กๆอย่างหนึ่งที่ถูกเพิ่มเข้ามา



ฟังก์ชัน print
เรื่องการใช้คำสั่ง print นี้เป็นตัวอย่างหนึ่งของความเปลี่ยนแปลงที่ถูกยกมาพูดถึงบ่อยที่สุด

เดิมทีในไพธอน 2 คำสั่ง print มีโครงสร้างการใช้แบบนี้
print 'sawatdi'

นั่นคือ print แล้วเว้นวรรค ตามด้วยสิ่งที่ต้องการแสดงผลออกมา

แต่ว่าในไพธอน 3 ได้ถูกเปลี่ยนกลายเป็นแบบนี้
print('sawatdi')

ก็คือจำเป็นที่นะต้องใส่วงเล็บครอบสิ่งที่ต้องการแสดงผลออกมา หากไม่ใส่ก็จะขัดข้องไม่สามารถรันได้

อัน ที่จริงความเปลี่ยนแปลงนี้มีความหมายมากถึงระดับโครงสราง เพราะในไพธอน 2 print ถือว่าเป็นแค่คำสั่งหนึ่ง ไม่ใช่ฟังก์ชัน จึงมีรูปแบบการทำงานคล้ายกับ for หรือ while คือใช้การจัดวางโดยอาจจะเว้นวรรคหรือใส่วงเล็บก็ได้

แต่ในไพธอน 3 ถือว่ากลายเป็นฟังก์ชันไปโดยสมบูรณ์ เมื่อเป็นฟังก์ชันก็จะต้องมีวงเล็บ ( ) และสิ่งที่ต้องการพิมพ์ก็มีสถานะเป็นอาร์กิวเมนต์ของฟังก์ชัน

หากลองพิมพ์
type(print)
ในไพธอน 3 ก็จะได้ผลลัพธ์เป็น
builtin_function_or_method

แต่หากลองพิมพ์ในไพธอน 2 จะได้
SyntaxError: invalid syntax

ดังนั้นจะเห็นได้ว่าการเปลี่ยนแปลงวิธีการเขียนนี้เกิดขึ้นจากการเปลี่ยนแปลงไวยากรณ์ของภาษา

อนึ่ง ที่จริงแล้วในในไพธอน 2 จะใส่วงเล็บก็ได้เหมือนกัน เพียงแต่ว่าหากมีจุลภาค , อยู่ในข้อความจะให้ผลที่แตกต่างจากไพธอน 3

ลองเปรียบเทียบ

print('nǐhǎo','konnichiwa')
ในไพธอน 3 ได้ผลเป็น
nǐhǎo konnichiwa

ส่วนในไพธอน 2 ได้ผลเป็น
('n\xc7\x90h\xc7\x8eo', 'konnichiwa')
นั่นคือผลออกมาเป็นทูเพิล แทนที่จะเป็นข้อความต่อกัน จะเห็นได้ว่าการใส่วงเล็บถูกตีความไปต่างกัน

แน่นอนว่าเมื่อใส่วงเล็บแล้วได้ทูเพิล หากลองใส่เป็นวงเล็บเหลี่ยมเช่น
print['nǐhǎo','konnichiwa']
ผลที่ได้ก็จะกลายเป็นลิสต์

ในขณะที่ถ้าต้องการให้แสดงผลเหมือนกับในไพธอน 3 ก็จะต้องไม่ใส่วงเล็บ นั่นคือ
print'nǐhǎo','konnichiwa'

อย่างไร ก็ตาม ความเปลี่ยนแปลงนี้เกิดขึ้นที่คำสั่ง print แต่สำหรับ if และ while ไม่มีอะไรเปลี่ยนแปลง ยังคงสามารถใส่หรือไม่ใส่วงเล็บก็ได้

อีกเรื่องหนึ่งคือการพิมพ์เพื่อให้ขึ้นบรรทัดต่อ ถ้าเป็นในไพธอน 3 พิมพ์เป็น
print('ความรักก็เป็นแค่ bug อย่างหนึ่ง', end='')
print('ที่เกิดขึ้นจากปฏิกิริยาทางไฟฟ้าในสมองเท่านั้น')
ได้ผลเป็น
ความรักก็เป็นแค่ bug อย่างหนึ่งที่เกิดขึ้นจากปฏิกิริยาทางไฟฟ้าในสมองเท่านั้น

แต่ในไพธอน 2 ต้องพิมพ์เป็น
print'ความรักก็เป็นแค่ bug อย่างหนึ่ง',
print'ที่เกิดขึ้นจากปฏิกิริยาทางไฟฟ้าในสมองเท่านั้น'
ได้ผลเป็น
ความรักก็เป็นแค่ bug อย่างหนึ่ง ที่เกิดขึ้นจากปฏิกิริยาทางไฟฟ้าในสมองเท่านั้น
(ที่มาของข้อความ http://hinaboshi.com/walidet/620548994630542)



ฟังก์ชัน input
ในไพธอน 2 นั้นฟังก์ชัน input จะเป็นการใส่ข้อมูลที่เป็นตัวเลข แต่หากจะใส่สายอักขระต้องเป็น raw_input

แต่ในไพธอน 3 ถูกแก้ให้ input เป็นการนำเข้าสายอักขระเท่านั้น และฟังก์ชัน raw_input ก็หายไป ไม่สามารถใช้ได้แล้ว

ยกตัวอย่าง เช่น
a = input()

แล้วลองพิมพ์ข้อความอะไรก็ได้เข้าไปโดยที่ไม่ใส่เครื่องหมายคำพูดคร่อม

ในไพธอน 3 จะไม่มีอะไรเกิดขึ้น ค่าของสายอักขระเข้าไปเก็บในตัวแปร a ตามปกติ แต่ในไพธอน 2 จะขึ้นว่า
NameError: name 'ข้อความอะไรก็ได้' is not defined

แต่ก็สามารถใส่สายอักขระได้โดยใส่เครื่องหมายคำพูดคร่อม

สรุปแล้วคือฟังก์ชัน input ในไพธอน 2 สามารถใส่ข้อมูลได้ทุกชนิด

ในขณะที่ในไพธอน 3 นั้นข้อมูลที่พิมพ์ไปจะกลายเป็นสายอักขระไปหมด แม้ว่าจะพิมพ์ตัวเลขก็ตาม

เช่นใส่ 12 ลงไปจากนั้น print(a) ถ้าเป็นไพธอน 3 จะได้เป็น '12' ออกมา คือเป็นสายอักขระที่เก็บอักษรตัวเลข 1 และ 2
ในขณะที่ถ้าเป็นไพธอน 2 จะได้เป็น 12 ซึ่งเป็นตัวเลขเลย

ในไพธอน 3 หากต้องการจะได้เป็นตัวเลขก็ต้องแปลงอีกต่อ เช่น
a = int(input())
b = float(input())

ความแตกต่างตรงนี้จำเป็นจะต้องระวังให้ดี เพราะให้ผลแตกต่างกันมากพอสมควร



การหารจำนวนเต็ม
ในไพธอน 2 นั้นจำนวนเต็มหารจำนวนเต็มจะได้จำนวนเต็มเช่นเดิม และหากเหลือเศษจะมีการปัดเศษให้เป็นจำนวนเต็ม

แต่ในไพธอน 3 จำนวนเต็มหารจำนวนเต็มจะได้จำนวนจริง ซึ่งมีทศนิยมได้ ดังนั้นจะไม่มีการปัดเศษ
ยกตัวอย่าง
print(5/3)

ในไพธอน 3 จะได้
1.6666666666666667

นั่นคือข้อมูลถูกเปลี่ยนเป็นจำนวนจริงซึ่งมีทศนิยมได้

ส่วนในไพธอน 2 จะได้
1
นั่น คือยังคงเป็นจำนวนเต็มอยู่ หารแล้วเศษจะโดนปัดทิ้งไปหมด โดยการปัดเศษนี้ไม่ใช่การปัดแบบประมาณค่า แต่เป็นการเอาเศษออกให้หมด แม้ว่าเศษนั้นจะเกิน 0.5 ก็ถูกปัดลง

นี่เป็นข้อแตกต่างสำคัญที่อาจ ต้องจำเอาไว้ เวลาที่ไปเขียนภาษาอื่นก็จะเจอทั้งภาษาที่มีการปัดและไม่มีการปัด อาจต้องจำแยก แต่หากไม่อยากวุ่นวายขอแนะนำว่าให้แปลงเป็นเลขจำนวนจริงทุกครั้งที่รู้ว่า หารแล้วอาจมีเศษ เพราะหากใช้ไพธอน 3 จนชินแล้วพอไปใช้ไพธอน 2 แล้วไปใช้ความเคยชินแบบเดิมก็จะได้ผลการคำนวณที่ผิดพลาดได้

สามารถแก้ปัญหาในไพธอน 2 ได้ไม่ยาก ด้วยการเติมจุดทศนิยมหลังจำนวนใดจำนวนหนึ่งที่ร่วมคำนวณ
5./3

เท่านี้ก็จะได้ผลเป็นจำนวนที่มีทศนิยมแล้ว



การยกกำลังจำนวนติดลบ
ในโลกของความเป็นจริงแล้วจำนวนติดลบก็สามารถยกกำลังได้ เพียงแต่จะออกมาเป็นจำนวนเชิงซ้อน

แต่ในไพธอน 2 หากจำนวนติดลบยกกำลังก็จะขัดข้องทันที ในขณะที่ในไพธอน 3 จะเปลี่ยนเป็นข้อมูลชนิดจำนวนเชิงซ้อนให้เลย เช่น
(-2)**1.1

ในไพธอน 3 ได้
(-2.0386342710747223-0.6623924280875919j)

แต่ในไพธอน 2 ได้
ValueError: negative number cannot be raised to a fractional power

ใน ไพธอน 2 จำนวนจริงไม่ถูกเปลี่ยนเป็นจำนวนเชิงซ้อนโดยอัตโนมัติ จึงจำเป็นต้องเปลี่ยนชนิดข้อมูลให้เป็นจำนวนเชิงซ้อนก่อน โดยเขียนเป็น
complex(-2)**1.1
หรือ
(-2+0j)**1.1



ชนิดข้อมูลของสายอักขระ
รายละเอียดแยกเขียนเอาไว้ใน https://phyblas.hinaboshi.com/20151219



ชนิดข้อมูลของ range
รายละเอียดแยกเขียนเอาไว้ใน https://phyblas.hinaboshi.com/20151218



การจัดการกับตัวแปรที่ใช้ใน for
ในไพธอน 3 เมื่อใช้คำสั่ง for สำหรับสร้างลิสต์ ตัวแปรนั้นจะถูกแยกออกเป็นคนละโลกกับตัวแปรภายนอก กล่าวคือต่อให้ชื่อตัวแปรซ้ำกันก็จะไม่กระทบต่อตัวแปรนั้นที่อยู่นอกคำสั่ง สร้างลิสต์ เช่น
i=10
print('ค่า i ก่อน for:', i)
print('ค่า i ใน for:', [i for i in range(5)])
print('ค่า i หลัง for:', i)
จะได้ผลลัพธ์เป็น
ค่า i ก่อน for: 10
ค่า i ใน for: [0, 1, 2, 3, 4]
ค่า i หลัง for: 10

เพราะ กรณีนี้ตัวแปร i ที่นิยามก่อนเริ่มใช้คำสั่ง for สร้างลิสต์ กับตัวแปร i ที่อยู่ในคำสั่งนั้นเป็นคนละตัวกัน ดังนั้นต่อให้สร้างลิสต์เสร็จค่า i ที่นิยามขึ้นก่อนหน้าก็ไม่มีการเปลี่ยนแปลง
แต่ถ้าเป็นในไพธอน 2 จะไม่เป็นเช่นนั้น

i=10
print 'ค่า i ก่อน for:', i
print 'ค่า i ใน for:', [i for i in range(5)]
print 'ค่า i หลัง for:', i

ผลลัพธ์
ค่า i ก่อน for: 10
ค่า i ใน for: [0, 1, 2, 3, 4]
ค่า i หลัง for: 4

เพียง แต่ว่าความเปลี่ยนแปลงนี้เกิดเฉพาะสำหรับ for ที่ใช้สร้างลิสต์เท่านั้น สำหรับการใช้ for เป็นคำสั่งวนซ้ำยังทำให้เกิดการเปลี่ยนแปลงค่าตัวแปรเช่นเดิม

ไพธอน 3
i=10
print('ค่า i ก่อน for:', i)
print('ค่า i ใน for:',end=' ')
for i in range(5): print(i,end=' ')
print('\nค่า i หลัง for:', i)
ผลลัพธ์
ค่า i ก่อน for: 10
ค่า i ใน for: 0 1 2 3 4
ค่า i หลัง for: 4

ไพธอน 2
i=10
print 'ค่า i ก่อน for:', i
print 'ค่า i ใน for:',
for i in range(5): print i,
print '\nค่า i หลัง for:', i
ผลลัพธ์
ค่า i ก่อน for:  10
ค่า i ใน for: 0 1 2 3 4
ค่า i หลัง for: 4

จะเห็นว่าไม่มีการเปลี่ยนแปลง เพราะค่าของตัวแปร i ที่เปลี่ยนไปตามการวนซ้ำถือเป็นตัวเดียวกับ i ที่นิยามก่อนหน้านั้น



เมธอด keys, values และ items ของดิกชันนารี
ในไพธอน 2 เมธอด keys, values และ items จะคืนค่าลิสต์ของคีย์, ค่า และ ทูเพิลของคีย์และค่า ตามลำดับ เช่น
dic = {'a': 5, 'b': 3, 'd': 7}
print(dic.keys())
print(dic.values())
print(dic.items())
ได้
['a', 'b', 'd']
[5, 3, 7]
[('a', 5), ('b', 3), ('d', 7)]
แต่ในไพธอน 3 จะคืนค่าของข้อมูลซึ่งเป็นตัวชี้ถึงค่าในดิกชันนารี โดยจะได้เป็นออบเจ็กต์ชนิด dict_keys, dict_values และ dict_items
dict_keys(['d', 'b', 'a'])
dict_values([7, 3, 5])
dict_items([('d', 7), ('b', 3), ('a', 5)])

ซึ่งความจริงแล้วผลนี้เทียบเท่ากับเมธอด viewkeys, viewvalues และ viewitems ในไพธอน 2
print(dic.viewkeys())
print(dic.viewvalues())
print(dic.viewitems())
ได้
dict_keys(['a', 'b', 'd'])
dict_values([5, 3, 7])
dict_items([('a', 5), ('b', 3), ('d', 7)])

แต่ในไพธอน 3 เมธอดเหล่านี้ได้หายไป ถ้าพิมพ์แบบเดียวกันในไพธอน 3 จะขึ้นว่า
AttributeError: 'dict' object has no attribute 'viewkeys'

หากต้องการให้ผลของ keys, values และ items ในไพธอน 3 เหมือนอย่างในไพธอน 2 ก็อาจทำได้โดยแปลงเป็นลิสต์ด้วยฟังก์ชัน list อีกที
print(list(dic.keys()))
print(list(dic.values()))
print(list(dic.items()))

หรืออาจไม่มีความจำเป็นต้องแปลง หากนำไปใช้เช่นใช้กับ for ก็ใช้งานได้เหมือนกับลิสต์
for s in dic.items(): print(s, end=' ')
ได้
('d', 7) ('b', 3) ('a', 5)


ฟังก์ชัน map, filter และ zip
ในไพธอน 2 นั้น ฟังก์ชัน map เมื่อใช้แล้วจะคืนค่าออกมาเป็นลิสต์ ไม่ว่าจะใส่ลิสต์หรือทูเพิลหรือเซ็ต

map(float,(1,2,3)) # ได้ [1.0, 2.0, 3.0]


แต่ในไพธอน 3 ฟังก์ชัน map จะให้ผลออกมาเป็นอิเทอเรเตอร์ ต้องนำมาแปลงเป็นลิสต์ต่ออีกทีจึงจะสามารถแสดงผลได

map(float,(1,2,3)) # ได้ <map at 0x112383710>
list(map(float,(1,2,3))) # ได้ [1.0, 2.0, 3.0]


ส่วนฟังก์ชัน filter ในไพธอน 2 จะให้ผลเป็นลิสต์ถ้าใส่ลิสต์หรือเซ็ตเข้าไป และให้ผลเป็นทูเพิลถ้าใส่เป็นทูเพิล

filter(lambda x:x%2,[1,2,3]) # ได้ [1, 3]
filter(lambda x:x%2==0,(1,2,3)) # ได้ (2,)
filter(lambda x:x<3,{1,2,3}) # ได้ [1, 2]


แต่ไพธอน 3 จะให้ผลเป็นอิเทอเรเตอร์เสมอ ไม่ว่าจะใส่อะไร ต้องมาแปลงอีกที

filter(lambda x:x<3,{1,2,3}) # ได้ <filter at 0x112383eb8>
set(filter(lambda x:x<3,{1,2,3})) # ได้ {1, 2}


ส่วนฟังก์ชัน zip ในไพธอน 2 จะให้ผลเป็นลิสต์ของทูเพิล

zip({1,2},{3,4}) # ได้ [(1, 3), (2, 4)]
zip([1,2,3],[4,5,6]) # ได้ [(1, 4), (2, 5), (3, 6)]


แต่ในไพธอน 3 จะได้ผลเป็นอิเทอเรเตอร์ทั้งหมด พอแปลงเป็นลิสต์แล้วจึงจะได้ผลเหมือนในไพธอน 2

zip({1,2},{3,4}) # ได้ <zip at 0x11239e188>
list(zip([1,2,3],[4,5,6])) # ได้ [(1, 4), (2, 5), (3, 6)]




การใช้ฟังก์ชัน super
ในไพธอน 2 เวลาที่จะประกาศเรียกใช้ฟังก์ชัน super จากในซับคลาสเพื่อเรียกซูเปอร์คลาสจะมีกฏการเขียนที่ค่อนข้างเข้มงวด

class Clara(object):
     def __init__(self,x):
         self.x = x
class ClariS(Clara):
     def __init__(self,x,y):
         super(ClariS,self).__init__(x)
         self.y = y
c = ClariS(2,3)


จะเห็นว่าตอนที่ประกาศคลาสหลักจำเป็นต้องมี (object) อยู่ด้านหลัง และในฟังก์ชัน super ต้องใส่อาร์กิวเมนต์ ๒ ตัว เป็นตัวคลาสและตัวอินสแตนซ์

แต่ในไพธอน 3 สามารถละได้ทั้งหมด จึงเขียนแค่นี้ได้

class Clara:
     def __init__(self,x):
         self.x = x
class ClariS(Clara):
     def __init__(self,x,y):
         super().__init__(x)
         self.y = y
c = ClariS(2,3)


แต่จะเขียนเต็มๆแบบไพธอน 2 ก็ไม่ผิด สามารถเขียนได้เช่นกัน



ออบเจ็กต์ของความผิดพลาดในโครงสร้าง try except
ในไพธอน 2 เวลาที่ใช้ except หากต้องการให้มีตัวแปรมารับออบเจ็กต์ของความผิดพลาดเพื่อนำไปแสดงผลหรือทำอะไรจะใช้จุลภาค , เขียนต่อจากชนิดของข้อผิดพลาดไปเลย

import math

try:

     1/0

except Exception, er:

     print(type(er))

     print(er)


ได้
<type 'exceptions.ZeroDivisionError'>
integer division or modulo by zero

แต่ในไพธอน 3 จะใช้ as แทน นอกจากนี้ก็จะเห็นว่าข้อความที่แสดงตอนมีข้อผิดพลาดก็อาจต่างกันด้วย

import math
try:
    1/0
except Exception as er:
    print(type(er))
    print(er)
ได้
<class 'ZeroDivisionError'>
division by zero



เวลาที่นิยามคลาสของอิเทอเรเตอร์นั้นภายในโครงสร้างจะต้องนิยามเมธอดที่จะให้ทำงานเมื่อเจอฟังก์ชัน next

ซึ่งเมธอดนั้นในไพธอน 2 มีชื่อว่า next เฉยๆ ดังนั้นจึงเขียนแบบนี้

class Iternap:
     def __init__(self):
         self.n = 0
     def __iter__(self):
         return self
     def next(self):
         self.n += 1
     return self.n


แต่ในไพธอน 3 เมธอดนี้จะชื่อว่า __next__ โดยมีขีดล่างคร่อมเพิ่มเข้ามา ซึ่งจะเห็นว่าถูกเปลี่ยนให้สัมพันธ์กับเมธอดตัวอื่นๆที่มีคุณสมบัติพิเศษ

class Iternap:
     def __init__(self):
         self.n = 0
     def __iter__(self):
         return self
     def __next__(self):
         self.n += 1
     return self.n


เมธอดที่ถูกเปลี่ยนชื่อมีแค่ next เท่านั้น เมธอดอื่นๆเช่น __init__ และ __iter__ นั้นมีขีดล่างคร่อมมาตั้งแต่ไพธอน 2 แล้ว



มอดูล __future__
ไพธอน 2 สามารถนำคำสั่งบางอย่างจากไพธอน 3 มาใช้ได้โดยการนำเข้ามอดูล __future__

เช่นหากต้องการทำให้ print กลายเป็นฟังก์ชันอย่างที่เป็นอยู่ในไพธอน 3
from __future__ import print_function
print 1
ได้
SyntaxError: invalid syntax

จะเห็นว่าไม่สามารถใช้เว้นช่องได้แล้ว ต้องใส่วงเล็บแบบในไพธอน 3

print(1,1,1,1)
ได้
1 1 1 1

จะเห็นว่าออกมาเป็นเลขเรียงต่อกันแทนที่จะออกมาเป็นทูเพิลอย่างที่เคยเป็น



และนอกจากนี้ก็ยังมีรายละเอียดอื่นๆอีกหลายอย่างซึ่งในที่นี้ไม่อาจกล่าวถึงได้หมด


อ้างอิง


-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

目录

从日本来的名言
模块
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
机器学习
-- 神经网络
javascript
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  查看日志

  推荐日志

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ