ทำไมวิธีการแบบส่วนตัวของ Python จึงไม่เป็นแบบส่วนตัว


658

Python ช่วยให้เราสามารถสร้างวิธีการและตัวแปร 'ส่วนตัว' ภายในชั้นเรียนโดยการใส่เครื่องหมายขีดล่างคู่กับชื่อดังนี้: __myPrivateMethod(). แล้วจะอธิบายได้อย่างไร

>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
... 
>>> obj = MyClass()
>>> obj.myPublicMethod()
public method
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
>>> obj._MyClass__myPrivateMethod()
this is private!!

ตกลงคืออะไร!

ฉันจะอธิบายเรื่องนี้เล็กน้อยสำหรับผู้ที่ไม่ค่อยเข้าใจ

>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
... 
>>> obj = MyClass()

สิ่งที่ฉันทำคือสร้างชั้นเรียนด้วยวิธีสาธารณะและวิธีส่วนตัวและยกตัวอย่าง

ต่อไปฉันเรียกวิธีการสาธารณะ

>>> obj.myPublicMethod()
public method

ต่อไปฉันลองและเรียกวิธีการส่วนตัว

>>> obj.__myPrivateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: MyClass instance has no attribute '__myPrivateMethod'

ทุกอย่างดูดีที่นี่; เราไม่สามารถเรียกมันได้ ในความเป็นจริงแล้วมันเป็น 'ส่วนตัว' จริงๆแล้วมันไม่ใช่ การเรียกใช้dir ()บนวัตถุจะเผยให้เห็นวิธีการใหม่อันมหัศจรรย์ที่ไพ ธ อนสร้างขึ้นอย่างน่าอัศจรรย์สำหรับวิธีการ 'ส่วนตัว' ทั้งหมดของคุณ

>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']

ชื่อเมธอดใหม่นี้จะเป็นขีดล่างเสมอตามด้วยชื่อคลาสตามด้วยชื่อเมธอด

>>> obj._MyClass__myPrivateMethod()
this is private!!

มากสำหรับการห่อหุ้มใช่มั้ย

ไม่ว่าในกรณีใดฉันมักจะได้ยินว่า Python ไม่รองรับการห่อหุ้มดังนั้นทำไมถึงต้องลอง สิ่งที่ช่วยให้?


18
เช่นเดียวกับ Java หรือ C # ถ้าคุณใช้การสะท้อน (ซึ่งเป็นสิ่งที่คุณทำอยู่ที่นั่น)
0x434D53

4
มันถูกสร้างขึ้นเพื่อจุดประสงค์ในการทดสอบหน่วยดังนั้นคุณสามารถใช้ "แฮ็ค" เพื่อทดสอบหน่วยวิธีการส่วนตัวของชั้นเรียนของคุณจากภายนอก
waas1919

16
การทดสอบรูปแบบการต่อต้านไม่ใช่การทดสอบส่วนตัวหรือไม่ วิธีการส่วนตัวจะถูกใช้ในวิธีสาธารณะบางอย่างเพื่อให้แน่ใจว่ามันจะไม่ได้ใช้ตลอดไป และวิธีที่ถูกต้องในการทดสอบวิธีการส่วนตัว (จากการเรียนรู้ของฉันจนถึง ThoughtWorks) คือคุณเขียนข้อสอบสำหรับวิธีสาธารณะเท่านั้นที่ครอบคลุมทุกกรณี หากใช้งานได้ดีคุณไม่จำเป็นต้องทดสอบวิธีการส่วนตัวจากภายนอกเลย
พระนารายณ์ Narang

3
@VishnuNarang: ใช่นั่นคือสิ่งที่มักจะสอน แต่เช่นเคยวิธีการ "ทางศาสนา" เกือบทุกครั้งที่ " ทำเช่นนี้เสมอไม่เคยทำอย่างนั้น" เป็นสิ่งเดียวที่ "ไม่เคย" ดี หากการทดสอบหน่วยเป็น "เท่านั้น" ที่ใช้สำหรับการทดสอบการถดถอยหรือการทดสอบ API สาธารณะคุณไม่จำเป็นต้องทดสอบส่วนตัว แต่ถ้าคุณทำการพัฒนาหน่วยทดสอบขับเคลื่อนมีเหตุผลที่ดีในการทดสอบวิธีการเอกชนในระหว่างการพัฒนา (ตัวอย่างเช่นเมื่อมันยากที่จะเยาะเย้ยพารามิเตอร์ที่ผิดปกติ / มากผ่านอินเตอร์เฟซสาธารณะ) สภาพแวดล้อมการทดสอบภาษา / หน่วยบางอย่างไม่อนุญาตให้คุณทำเช่นนี้ซึ่ง IMHO นั้นไม่ดี
Marco Freudenberger

5
@ MarcoFreudenberger ฉันเห็นประเด็นของคุณ ฉันมีประสบการณ์ในการพัฒนาแบบทดสอบหน่วย บ่อยครั้งเมื่อมันกลายเป็นเรื่องยากที่จะเยาะเย้ยพารามิเตอร์ส่วนใหญ่มักจะได้รับการแก้ไขโดยการเปลี่ยนและปรับปรุงการออกแบบ ฉันยังไม่ได้เจอกับสถานการณ์ที่การออกแบบที่สมบูรณ์แบบและการทดสอบหน่วยยังคงเป็นเรื่องยากมากที่จะหลีกเลี่ยงการทดสอบวิธีการส่วนตัว ฉันจะระวังกรณีดังกล่าว ขอบคุณ ฉันขอขอบคุณถ้าคุณสามารถแบ่งปันเรื่องราวหนึ่งเรื่องจากหัวเพื่อช่วยให้ฉันเข้าใจได้
Vishnu Narang

คำตอบ:


592

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

ตัวอย่างเช่น:

>>> class Foo(object):
...     def __init__(self):
...         self.__baz = 42
...     def foo(self):
...         print self.__baz
...     
>>> class Bar(Foo):
...     def __init__(self):
...         super(Bar, self).__init__()
...         self.__baz = 21
...     def bar(self):
...         print self.__baz
...
>>> x = Bar()
>>> x.foo()
42
>>> x.bar()
21
>>> print x.__dict__
{'_Bar__baz': 21, '_Foo__baz': 42}

แน่นอนว่ามันจะพังถ้าสองคลาสที่ต่างกันมีชื่อเหมือนกัน


12
docs.python.org/2/tutorial/classes.html ส่วน: 9.6 เกี่ยวกับตัวแปรส่วนตัวและการอ้างอิงระดับท้องถิ่น
gjain

72
สำหรับพวกเราขี้เกียจเกินกว่าจะเลื่อน / ค้นหา: หมวดที่ 9.6 ลิงค์โดยตรง
cod3monk3y

3
คุณควรใส่เครื่องหมายขีดล่างเดี่ยวเพื่อระบุว่าตัวแปรควรถูกพิจารณาว่าเป็นส่วนตัว อีกครั้งนี่ไม่ได้ป้องกันไม่ให้ใครบางคนเข้าถึงได้
igon

14
กุยโด้ตอบคำถามนี้ - "เหตุผลหลักในการสร้าง (เกือบ) ทุกอย่างที่ค้นพบได้คือการดีบั๊ก: เมื่อทำการดีบั๊กคุณต้องฝ่าแนวนามธรรม" - ฉันเพิ่มมันเป็นความคิดเห็นเพราะมันสายเกินไป - คำตอบมากเกินไป
Peter M. - ย่อมาจาก Monica

1
หากคุณไปตามเกณฑ์ "ป้องกันการเข้าถึงโดยเจตนา" ภาษา OOP ส่วนใหญ่จะไม่สนับสนุนสมาชิกส่วนตัวอย่างแท้จริง ตัวอย่างเช่นใน C ++ คุณมีการเข้าถึงหน่วยความจำแบบดิบและในรหัสที่เชื่อถือได้ C # สามารถใช้การสะท้อนกลับส่วนตัว
CodesInChaos

207

ตัวอย่างของฟังก์ชั่นส่วนตัว

import re
import inspect

class MyClass :

    def __init__(self) :
        pass

    def private_function ( self ) :
        try :
            function_call = inspect.stack()[1][4][0].strip()

            # See if the function_call has "self." in the begining
            matched = re.match( '^self\.', function_call )
            if not matched :
                print 'This is Private Function, Go Away'
                return
        except :
            print 'This is Private Function, Go Away'
            return

        # This is the real Function, only accessible inside class #
        print 'Hey, Welcome in to function'

    def public_function ( self ) :
        # i can call private function from inside the class
        self.private_function()

### End ###

12
self = MyClass() self.private_function(). : D แน่นอนว่ามันไม่ทำงานในชั้นเรียน แต่คุณเพียงแค่ต้องกำหนดฟังก์ชั่นที่กำหนดเอง: def foo(self): self.private_function()
Casey Kuball

161
ในกรณีที่มันไม่ชัดเจน: ไม่เคยทำเช่นนี้ในรหัสจริง;)
Sudo ทุบตี

10
@ThorSummoner function_call.startswith('self.')หรือเพียงแค่
nyuszika7h

13
inspect.stack()[1][4][0].strip()<- หมายเลขมายากล 1, 4 และ 0 คืออะไร?
akhy

5
สิ่งนี้สามารถเอาชนะได้ง่ายมากโดยทำself = MyClass(); self.private_function()และล้มเหลวเมื่อเรียกใช้x = self.private_function()ในวิธีการ
จะ

171

ครั้งแรกที่ฉันมาจาก Java ถึง Python ฉันเกลียดสิ่งนี้ มันทำให้ฉันกลัวจนตาย

วันนี้มันอาจเป็นสิ่งเดียวที่ฉันชอบมากที่สุดเกี่ยวกับ Python

ฉันชอบที่จะอยู่บนแพลตฟอร์มที่ซึ่งผู้คนไว้วางใจซึ่งกันและกันและไม่รู้สึกว่าพวกเขาต้องการสร้างกำแพงที่ไม่ยอมรับรอบรหัสของพวกเขา ในภาษาที่มีการห่อหุ้มอย่างแน่นหนาหาก API มีข้อผิดพลาดและคุณพบสิ่งที่ผิดพลาดคุณอาจยังไม่สามารถแก้ไขได้เพราะวิธีการที่ต้องการนั้นเป็นแบบส่วนตัว ใน Python ทัศนคติคือ: "แน่ใจ" หากคุณคิดว่าคุณเข้าใจสถานการณ์บางทีคุณอาจเคยอ่านมาแล้วทั้งหมดที่เราสามารถพูดได้ก็คือ "ขอให้โชคดี!"

โปรดจำไว้ว่าการห่อหุ้มไม่ได้เกี่ยวข้องกับ "ความปลอดภัย" อย่างอ่อนแรงหรือทำให้เด็ก ๆ ออกจากสนามหญ้า มันเป็นเพียงรูปแบบอื่นที่ควรใช้เพื่อทำให้เข้าใจรหัสฐานได้ง่ายขึ้น


36
@CamJackson Javascript เป็นตัวอย่างของคุณหรือไม่? ภาษาที่ใช้กันอย่างแพร่หลายเท่านั้นที่มีการสืบทอดตามต้นแบบและภาษาที่สนับสนุนการเขียนโปรแกรมที่ใช้งานได้? ฉันคิดว่า JS เรียนรู้ได้ยากกว่าภาษาอื่น ๆ ส่วนใหญ่เนื่องจากใช้ขั้นตอนหลายขั้นตอนจาก OOP แบบดั้งเดิม ไม่ว่าสิ่งนี้จะช่วยป้องกันคนโง่จากการเขียน JS แต่พวกเขาก็ไม่รู้เหมือนกัน;)
K.Steff

23
API เป็นตัวอย่างที่ดีว่าทำไม encapsulation ถึงมีความสำคัญและควรเลือกใช้วิธีการส่วนตัวเมื่อใด วิธีที่ตั้งใจจะเป็นส่วนตัวอาจหายไปเปลี่ยนลายเซ็นหรือสิ่งที่แย่ที่สุดของพฤติกรรมการเปลี่ยนแปลงทั้งหมด - ทั้งหมดโดยไม่มีการเตือน - ในเวอร์ชันใหม่ที่ตามมา สมาชิกในทีมที่ฉลาดและเป็นผู้ใหญ่ของคุณจะจำได้หรือไม่ว่าเธอได้ใช้วิธีการที่ตั้งใจจะเป็นส่วนตัวเป็นเวลาหนึ่งปีนับจากนี้เมื่อคุณอัปเดต เธอจะทำงานที่นั่นอีกหรือไม่
einnocent

2
ฉันไม่เห็นด้วยกับข้อโต้แย้ง ในรหัสการผลิตฉันอาจจะไม่เคยใช้ API ที่มีข้อผิดพลาดที่ทำให้ฉันเปลี่ยนสมาชิกสาธารณะเพื่อให้มัน "ทำงาน" API ควรใช้งานได้ หากไม่เป็นเช่นนั้นฉันจะรายงานข้อผิดพลาดหรือสร้าง API เดียวกันเอง ฉันไม่ชอบปรัชญาและฉันไม่ชอบ Python มากแม้ว่าไวยากรณ์ของมันจะช่วยให้สนุกในการเขียนสคริปต์ที่มีขนาดเล็กใน ...
Yngve Sneen Lindal

4
Java มี Method.setAccessible และ Field.setAccessible ยังน่ากลัวเหรอ?
โทนี่

15
การบังคับใช้ใน Java และ C ++ นั้นไม่ใช่เพราะ Java ทำให้ผู้ใช้ไม่ไว้วางใจในขณะที่ Python ทำ มันเป็นเพราะคอมไพเลอร์และ / หรือ vm สามารถสร้างสมมติฐานต่าง ๆ เมื่อจัดการกับธุรกิจของมันถ้ามันรู้ข้อมูลนี้เช่น C ++ สามารถข้ามเลเยอร์ทั้งหมดของการอ้อมโดยใช้การโทร C ปกติแบบเก่าแทนการโทรเสมือน ไม่ว่าคุณจะทำงานที่มีประสิทธิภาพสูงหรือมีความแม่นยำสูง Python ไม่สามารถใช้ประโยชน์จากข้อมูลได้อย่างแท้จริง ทั้งสองภาษาต่างเล็งไปที่สิ่งที่แตกต่างกันดังนั้นจึงไม่มี "ผิด"
Shayne

144

จากhttp://www.faqs.org/docs/diveintopython/fileinfo_private.html

การพูดอย่างเคร่งครัดสามารถใช้วิธีส่วนตัวได้นอกชั้นเรียนไม่สามารถเข้าถึงได้ง่าย ไม่มีอะไรใน Python ที่เป็นส่วนตัวอย่างแท้จริง ภายในชื่อของเมธอดและแอ็ตทริบิวต์ส่วนตัวถูกทำให้ยุ่งเหยิงและไม่ถูกโยงในทันทีเพื่อทำให้ชื่อเหล่านั้นดูเหมือนไม่สามารถเข้าถึงได้ คุณสามารถเข้าถึงวิธี __parse ของคลาส MP3FileInfo ด้วยชื่อ _MP3FileInfo__parse รับทราบว่าสิ่งนี้น่าสนใจจากนั้นสัญญาว่าจะไม่ทำในรหัสจริง วิธีการแบบส่วนตัวนั้นมีความเป็นส่วนตัวด้วยเหตุผล แต่เช่นเดียวกับสิ่งอื่น ๆ ใน Python ความเป็นส่วนตัวของพวกเขานั้นเป็นเรื่องของการประชุมไม่ใช่การบังคับ


202
หรืออย่างที่ Guido van Rossum กล่าวไว้: "พวกเราทุกคนล้วนเป็นผู้ใหญ่"

35
-1: นี่มันผิด เครื่องหมายขีดล่างคู่ไม่ได้หมายถึงการใช้เป็นส่วนตัวตั้งแต่แรก คำตอบจาก Alya ด้านล่างจะบอกถึงเจตนาแท้จริงของไวยากรณ์ชื่อการโยง การประชุมที่แท้จริงคือขีดล่างเดียว
nosklo

2
ลองขีดเส้นใต้เพียงอันเดียวแล้วคุณจะเห็นผลลัพธ์ที่คุณได้รับ @nosklo
Billal Begueradj

93

วลีที่ใช้กันทั่วไปคือ "เราทุกคนยินยอมผู้ใหญ่ที่นี่" โดยการขีดเส้นใต้เดียว (ไม่เปิดเผย) หรือขีดเส้นใต้คู่ (ซ่อน) คุณกำลังบอกผู้ใช้ชั้นเรียนของคุณว่าคุณต้องการให้สมาชิกเป็น 'ส่วนตัว' อย่างใด อย่างไรก็ตามคุณเชื่อมั่นว่าคนอื่น ๆ จะมีความรับผิดชอบและเคารพหากพวกเขามีเหตุผลที่น่าสนใจที่จะไม่ (เช่น debuggers, การกรอกโค้ด)

หากคุณต้องมีสิ่งที่เป็นส่วนตัวคุณสามารถนำไปใช้ในส่วนขยาย (เช่นใน C สำหรับ CPython) อย่างไรก็ตามในกรณีส่วนใหญ่คุณเพียงแค่เรียนรู้วิธีการทำสิ่งต่าง ๆ ของ Pythonic


ดังนั้นจะมีโปรโตคอล wrapper บางอย่างที่ฉันควรจะใช้เพื่อเข้าถึงตัวแปรที่ได้รับการป้องกันหรือไม่?
สัญชาตญาณ

3
ไม่มีตัวแปร "ที่ได้รับการป้องกัน" มากกว่าที่จะเป็น "ส่วนตัว" หากคุณต้องการเข้าถึงแอตทริบิวต์ที่ขึ้นต้นด้วยเครื่องหมายขีดล่างคุณสามารถทำได้ (แต่โปรดทราบว่าผู้เขียนไม่สนับสนุนสิ่งนี้) หากคุณต้องเข้าถึงแอตทริบิวต์ที่ขึ้นต้นด้วยเครื่องหมายขีดล่างคู่คุณสามารถทำชื่อ mangling ด้วยตัวคุณเอง แต่คุณไม่ต้องการทำเช่นนี้
Tony Meyer

33

ไม่ใช่ว่าคุณไม่สามารถเข้าถึงความเป็นส่วนตัวของสมาชิกในภาษาใด ๆ ได้อย่างแน่นอน (ตัวชี้เลขใน C ++, Reflections in .NET / Java)

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

แก้ไข: คุณไม่พยายามรักษาความปลอดภัยข้อมูลของคุณโดย OO-encapsulation ใช่ไหม?


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

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

7
ใน Java คุณสามารถรักษาความปลอดภัยของข้อมูลผ่านการห่อหุ้ม แต่คุณต้องฉลาดและรันรหัสที่ไม่น่าเชื่อถือใน SecurityManager และระวังให้มาก แม้แต่ Oracle ก็ทำให้มันผิด
พลวง

12

class.__stuffตั้งชื่อการประชุมช่วยให้โปรแกรมเมอร์ที่รู้ว่าเขาไม่ได้หมายถึงการเข้าถึง__stuffจากภายนอก ชื่อ mangling ทำให้ไม่น่าที่ใครจะทำโดยบังเอิญ

จริงอยู่ที่คุณยังสามารถแก้ไขได้มันง่ายกว่าในภาษาอื่น ๆ (ซึ่ง BTW อนุญาตให้คุณทำเช่นนี้) แต่ไม่มีโปรแกรม Python ที่จะทำสิ่งนี้ถ้าเขาสนใจเรื่องแค็ปซูล


12

พฤติกรรมที่คล้ายกันเกิดขึ้นเมื่อชื่อแอ็ตทริบิวต์ของโมดูลเริ่มต้นด้วยเครื่องหมายขีดล่างเดียว (เช่น _foo)

แอตทริบิวต์ของโมดูลที่มีชื่อเช่นนี้จะไม่ถูกคัดลอกไปยังโมดูลการนำเข้าเมื่อใช้from*วิธีการเช่น:

from bar import *

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


12

เป็นเพียงหนึ่งในตัวเลือกการออกแบบภาษาเหล่านั้น ในบางระดับพวกเขามีความชอบธรรม พวกเขาทำมันดังนั้นคุณต้องไปให้ไกลจากการพยายามโทรหาวิธีและถ้าคุณต้องการมันมากจริงๆคุณต้องมีเหตุผลที่ดี!

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


4

ด้วย Python 3.4 นี่คือพฤติกรรม:

>>> class Foo:
        def __init__(self):
                pass
        def __privateMethod(self):
                return 3
        def invoke(self):
                return self.__privateMethod()


>>> help(Foo)
Help on class Foo in module __main__:

class Foo(builtins.object)
 |  Methods defined here:
 |
 |  __init__(self)
 |
 |  invoke(self)
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  __dict__
 |      dictionary for instance variables (if defined)
 |
 |  __weakref__
 |      list of weak references to the object (if defined)

 >>> f = Foo()
 >>> f.invoke()
 3
 >>> f.__privateMethod()
 Traceback (most recent call last):
   File "<pyshell#47>", line 1, in <module>
     f.__privateMethod()
 AttributeError: 'Foo' object has no attribute '__privateMethod'

https://docs.python.org/3/tutorial/classes.html#tut-private

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

แม้ว่าคำถามจะเก่า แต่ฉันหวังว่าข้อมูลโค้ดของฉันจะมีประโยชน์


2

ความกังวลที่สำคัญที่สุดเกี่ยวกับวิธีการและคุณลักษณะส่วนตัวคือบอกนักพัฒนาไม่ให้เรียกมันนอกคลาสและนี่คือการห่อหุ้ม หนึ่งอาจเข้าใจผิดความปลอดภัยจากการห่อหุ้ม เมื่อมีการใช้ไวยากรณ์โดยเจตนาเช่นนั้น (ตะโกน) ที่คุณพูดถึงคุณไม่ต้องการ encapsulation

obj._MyClass__myPrivateMethod()

ฉันได้ย้ายจาก C # และในตอนแรกมันก็แปลกสำหรับฉันเช่นกัน แต่หลังจากนั้นไม่นานฉันก็คิดว่าวิธีเดียวที่ Python ออกแบบรหัสคิดเกี่ยวกับ OOP นั้นแตกต่างกัน


1

ทำไมวิธีการแบบส่วนตัวของ Python จึงไม่เป็นแบบส่วนตัว

เมื่อฉันเข้าใจแล้วพวกเขาไม่สามารถเป็นส่วนตัวได้ ความเป็นส่วนตัวสามารถบังคับใช้อย่างไร

คำตอบที่ชัดเจนคือ "สมาชิกส่วนตัวเท่านั้นที่สามารถเข้าถึงได้ผ่านself" แต่นั่นไม่ได้ผล - selfไม่ใช่พิเศษใน Python มันไม่มีอะไรมากไปกว่าชื่อที่ใช้กันทั่วไปสำหรับพารามิเตอร์แรกของฟังก์ชัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.