ไพธอนเป็นหนึ่งในภาษาที่เป็น Object Oriented ซึ่งต่างจาก procedure oriented language ที่จะเน้นการใช้งานเป็นฟังก์ชัน แต่ Object Oriented จะเน้นการใช้งานในรูปแบบออบเจค
โดยออบเจ็คแต่ละชนิดนั้นประกอบด้วยข้อมูลตัวแปรและฟังก์ชันเพื่อมาใช้ทำงานกับข้อมูลต่างๆ และคลาสซึ่งเป็นการกำหนดรูปแบบให้ออบเจ็คแต่ละชนิด
เราสามารถเปรียบเทียบคลาสเป็นเหมือนโครงร่างของบ้าน ซึ่งจะประกอบด้วยข้อมูลของพื้น, ประตู, หน้าต่าง และอื่นๆ ขึ้นอยู่กับรายละเอียดนี้เราสามารถประกอบเป็นบ้าน โดยบ้านเป็นออบเจ็คหนึ่ง ซึ่งบ้านหลายๆหลังสามารถสร้างจากการรายละเอียดเริ่มต้นเหล่านี้ ซึ่งสามารถสร้างเป็นออบเจ็คได้หลายแบบจากคลาสเดียวกันซึ่งจะเรียกว่า instance ของคลาส
การกำหนดคลาสในไพธอน
สำหรับการกำหนดฟังก์ชันเราจะเริ่มต้นประกาศฟังก์ชันด้วยคีย์เวิร์ด def แต่สำหรับการกำหนดคลาสเราจะเริ่มต้นประกาศคลาสด้วยคีย์เวิร์ด class โดยสิ่งแรกที่มักประกาศคือ docstring ซึ่งเป็นข้อควาที่ระบุข้อมูลคร่างๆ เกี่ยวกับคลาสนั้นๆ แต่ก็ไม่ได้บังคับตายตัวว่าจำเป็นต้องใส่ทุกครั้ง แต่การใส่จะทำให้เมื่อกลับมาอ่านแล้วสามารถจะทำความเข้าใจเกี่ยวกับคลาสได้รวดเร็วขึ้น
ตัวอย่างการใช้งาน
class abc
''' docstring here '''
pas
คลาสจะทำการสร้าง local namespace ขึ้นมาใหม่ซึ่งใช้ประกาศแอทริบิวต์หรือฟังก์ชัน และยังมีแอททริบิวท์พิเศษที่เริ่มต้นชื่อด้วย __ เช่น __doc__ ใช้กำหนดรายละเอียด docstring ของคลาส
เมื่อเราทำการกำหนดคลาส ออบเจ็คของคลาสใหม่จะถูกสร้างด้วยชื่อเดียวกัน โดยออบเจ็คนี้อนุญาติให้เข้าถึงข้อมูลแอทริบิวต์และสร้างออบเจ็คใหม่ของคลาสนั้น
ตัวอย่างการใช้งาน
class MyClass:
"This is my second class"
a = 10
def func(self):
print('Hello')
# Output: 10
print(MyClass.a)
# Output:
print(MyClass.func)
# Output: 'This is my second class'
print(MyClass.__doc__)
การสร้างออบเจ็ค
นอกจากเราสามารถใช้ออบเจ็คของคลาสเพื่อเข้าถึงข้อมูลแอทริบิวท์ต่างๆ เรายังสามารถใช้เพื่อสร้างออบเจ็ค instance ของคลาสนั้นๆ ได้ด้วย วิธีการสร้างออบเจ็คเหมือนกับการเรียกใช้ฟังก์ชัน
ตัวอย่างการใช้งาน
newobj = NameObj()
จากตัวอย่างจะทำการสร้างออบเจ็ค instance ชื่อว่า ob เราสามารถเข้าถึงข้อมูลแอทริบิวท์ของออบเจ็คโดยใช้ชื่อออบเจ็คในการขึ้นต้น
โดยคุณลักษณะที่จะเข้าถึงอาจจะเป็นข้อมูล หรือเมทธอด โดยเมทธอดของออบเจ็คนั้นสัมพันธ์กับฟังก์ชันของคลาส ฟังก์ชันของออบเจ็คใดคือแอทริบิวท์ของคลาส สำหรับกำหนดเมทธอดของออบเจ็คของคลาสนั้น
เช่น MyClass.func เป็นฟังก์ชันของออบเจค(แอทริบิวท์ของคลาส) obj.func จะเป็นเมทธอดของออบเจ็ค
class MyClass:
"This is my second class"
a = 10
def func(self):
print('Hello')
# create a new MyClass
ob = MyClass()
# Output:
print(MyClass.func)
# Output: >
print(ob.func)
# Calling function func()
# Output: Hello
ob.func()
เราอาจจะพบตัวแปร self ในการกำหนดฟังก์ชันของคลาส แต่ว่าเวลาเราต้องการเรียกใช้เมทธอดเราเรียกใช้โดยไม่ทำการระบุค่านี้เข้าไปเช่น obj.func() เนื่องจากทุกครั้งที่ออบเจคทำการเรียกใช้เมทธอด ตัวออบเจคเองจะถูกส่งเข้าไปเป็นตัวแปรแรกเสมอ ดังนั้นเมื่อเราเรียก obj.func() สิ่งที่เกิดขึ้นคือจะถูกแปลงเป็น NewClass.func(obj) ซึ่งโดยทั่วไปเมื่อมีการเรียกใช้งานเมทธอดพร้อมกับลิสต์ของตัวแปร n ตัว จะเทียบเท่ากับการเรียกใช้งานฟังก์ชันพร้อมทั้งลิสต์ของตัวแปรนั้น ซึ่งถูกสร้างขึ้นโดยทำการเพิ่ม ออบเจคของเมทธอดเข้าไปเป็นตัวแรกของกลุ่มตัวแปร
ด้วยเหตุผลดังกล่า ตัวแปรแรกของฟังก์ชันของคลาสจะต้องเป็นตัวออบเจคเอง ซึ่งก็คือ self ชื่อนี้อาจะถูกเปลี่ยนเป็นชื่ออื่นๆ ได้ แต่เพื่อความเข้าใจง่าย ใช้ชื่อ self น่าจะทำให้เข้าใจเวลาอ่านโค้ดมากกว่า
constructors
คลาสฟังก์ชันที่เริ่มต้นชื่อด้วย __ นั้นเรียกว่าฟังก์ชันพิเศษ หนึ่งในฟังก์ชันลักษณะดังกล่าว คือ ฟังก์ชัน __init__() โดยฟังก์ชันนี้จะถูกเรียกใช้เสมอเมื่อมีการสร้าง instance ของออบเจคใหม่ ซึ่งฟังก์ชันนี้จะเรียกว่า constructor สำหรับ OOP ซึ่งมักจะถูกนำไปใช้สำหรับทำการกำหนดค่าตั้งตั้งให้กับคลาสนั้น
ตัวอย่างการใช้งาน
class ComplexNumber:
def __init__(self,r = 0,i = 0):
self.real = r
self.imag = i
def getData(self):
print("{0}+{1}j".format(self.real,self.imag))
# Create a new ComplexNumber object
c1 = ComplexNumber(2,3)
# Call getData() function
# Output: 2+3j
c1.getData()
# Create another ComplexNumber object
# and create a new attribute 'attr'
c2 = ComplexNumber(5)
c2.attr = 10
# Output: (5, 0, 10)
print((c2.real, c2.imag, c2.attr))
# but c1 object doesn't have attribute 'attr'
# AttributeError: 'ComplexNumber' object has no attribute 'attr'
c1.attr
จากตัวอย่าง เรากำหนดคลาสใหม่ซ฿่งแสดงข้อมูลจำนวนเชิงซ้อน โดยกำหนดให้คลาสมี 2 ฟังก์ชันคือ __init__() เพื่อจะกำหนดค่าตั้งต้นให้ตัวแปร และ getData() เพื่อจะแสดงจำนวนด้วยรูปแบบที่เหมาะสม
ประเด็นที่น่าสนใจคือ แอทริบิวท์ของออบเจคสามารถจะถูกสร้างตอนโปรแกรมทำงานแล้วได้ จากตัวอย่างเราทำการสร้างแอทริบิวท์ใหม่ชื่อ attr ตอนโปรแกรมถูกใช้งานไปแล้วสำหรับออบเจค c2 และอ่านค่าออกมาด้วย แต่ไม่ได้สร้างทำการสร้าง attribute attr สำหรับออบเจค c1 หากมีการเรียกใช้งานอาจทำให้เกิดข้อผิดพลาดได้
การลบข้อมูลแอทริบิวท์ และ ออบเจค
เราสามารถลบข้อมูลแอทริบิวท์หรือออบเจคโดยใช้คีย์เวิร์ด del
ตัวอย่างการใช้งาน
c1 = ComplexNumber(2, 3) del c1.imag c1.getData() Traceback (most recent call last): ... AttributeError: 'ComplexNumber' object has no attribute 'imag' del ComplexNumber.getData c1.getData() Traceback (most recent call last): ... AttributeError: 'ComplexNumber' object has no attribute 'getData' del c1 c1 Traceback (most recent call last): ... NameError: name 'c1' is not defined
แต่ในระบบด้านหลังนั้นจะซับซ้อนกว่า ตรงที่เมื่อเรากำหนด c1 = ComplexNumber(1, 3) instance ใหม่ของออบเจคได้ถูกสร้างขึ้นในหน่วยความจำและชื่อ c1 ได้ถูก bind ไว้กับหน่วยความจำนั้น เมื่อใช้คำสั่ง del c1 ข้อมูลการ bind ได้ถูกลบออกและชื่อ c1 ได้ถูกลบออกจาก namespace แต่ตัวออบเจคเองนั้นยังคงอยู่ในหน่วยความจำ ถ้าไม่มีชื่อใดมาทำการ bind ไว้ ออบเจคนั้นจึงค่อยถูกลบออกอัตโนมัติ ซึ่งการลบออบเจคที่ไม่มีการอ้างถึงนี้อัตโนมัติดนั้นเรียกว่า garbage collection