Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

ตัวแปรส่วนตัว (Private Variables) ในคลาสของ Python

ในบทช่วยสอนนี้ เราจะเรียนรู้เกี่ยวกับ ตัวแปรส่วนตัว (private variables) ใน คลาส (classes) ของ Python

Python ไม่มีแนวคิด Private Variables โดยตรง

Python ไม่มีกลไกการเข้าถึงแบบ private จริงๆ เช่นภาษา Java หรือ C++ แต่ผู้พัฒนาส่วนใหญ่ปฏิบัติตาม ข้อตกลงการตั้งชื่อ (naming convention) เพื่อบ่งชี้ว่า ตัวแปรนั้นไม่ควรเข้าถึงจากภายนอกโดยตรง

ข้อตกลงการตั้งชื่อด้วย Double Underscore

การขึ้นต้นชื่อตัวแปรด้วย underscore สองตัว (__) จะบอกให้เข้าใจว่าเป็นตัวแปร "ส่วนตัว" (แต่ไม่ได้ห้ามเข้าถึงจริงๆ) ตัวอย่างเช่น __name, __balance เป็นต้น

ตัวอย่าง: การสร้างและเข้าถึงตัวแปรแบบ "ส่วนตัว"

class Sample:
    def __init__(self, nv, pv):
        # ตัวแปรทั่วไป (public)
        self.nv = nv
        # ตัวแปร "ส่วนตัว" (name mangling จะเปลี่ยนชื่อ)
        self.__pv = pv

# สร้างอินสแตนซ์
sample = Sample('Normal variable', 'Private variable')

# เข้าถึงตัวแปรทั่วไป - ทำงานปกติ
print(sample.nv)  # Normal variable

# พยายามเข้าถึง __pv โดยตรง - จะเกิด AttributeError
print(sample.__pv)  # AttributeError: 'Sample' object has no attribute '__pv'

ทำไมถึงเกิด AttributeError?

Python ทำการ Name Mangling (การเปลี่ยนชื่อ) ให้กับตัวแปรที่ขึ้นต้นด้วย __ โดยเปลี่ยนชื่อเป็นรูปแบบ _ClassName__variableName ดังนั้น __pv ในคลาส Sample จะกลายเป็น _Sample__pv

วิธีเข้าถึงตัวแปรที่ถูก Name Mangling

# เข้าถึงผ่านชื่อที่ถูก mangle แล้ว
print(sample._Sample__pv)  # Private variable

Name Mangling ยังใช้กับเมธอดได้เช่นกัน

class Sample:
    def __init__(self, a):
        self.a = a
    
    # เมธอด "ส่วนตัว"
    def __get_a(self):
        return self.a

sample = Sample(5)

# เรียกผ่านชื่อที่ mangle แล้ว - ทำงานได้
print(sample._Sample__get_a())  # 5

# เรียกโดยตรง - จะ error
print(sample.__get_a())  # AttributeError

สรุป

จุดประสงค์ของ __ (double underscore) ไม่ใช่เพื่อป้องกันการเข้าถึง แต่เป็นสัญญาณบอกว่า ตัวแปร/เมธอดนี้ ตั้งใจจะใช้ภายในคลาสเท่านั้น การเข้าถึงจากภายนอกยังทำได้ แต่ควรหลีกเลี่ยงเพื่อรักษา encapsulation และลดการพึ่งพารายละเอียดภายใน (implementation details)


หากมีข้อสงสัยเกี่ยวกับบทช่วยสอนนี้ สามารถถามได้ในส่วนความคิดเห็นครับ