ทำไมไม่มีตัวดัดแปลงการเข้าถึงที่ชัดเจนใน Python:


28

หาก 'ชัดเจนดีกว่านัย' เหตุใดจึงไม่มีการปรับเปลี่ยนการเข้าถึงอย่างชัดเจนใน Python: สาธารณะการป้องกันส่วนตัว ฯลฯ

ฉันรู้ว่าความคิดนี้คือโปรแกรมเมอร์ควรรู้ว่าต้องทำอะไรผ่านคำใบ้ - ไม่จำเป็นต้องใช้ 'กำลังดุร้าย' แต่ IMO 'Encapsulation' หรือ 'การซ่อนข้อมูล' ไม่เพียง แต่จะช่วยให้ผู้คนออกไปมันเป็นคำถามขององค์กรและโครงสร้าง: เลเยอร์การพัฒนาของคุณควรมีการกำหนดขอบเขตและเส้นขอบที่กำหนดขอบเขตได้เองอย่างชัดเจนเหมือนกับระบบทางกายภาพ

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

แก้ไข: จนถึงตอนนี้ฉันเห็นคำตอบที่เสนอมา 3 ข้อแล้วและฉันก็รู้ว่าคำถามของฉันมี 2 ส่วน:

  1. ทำไมไม่มีคำสำคัญเช่น

    private def myFunc(): 
        dostuff....

    แทน IMO ผู้น่าเกลียดและยากที่จะพิมพ์ขีดล่าง แต่นั่นไม่ใช่ประเด็นสำคัญ

  2. ที่สำคัญกว่า:

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

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

เท่าที่ฉันรัก Python ฉันพบว่าจุดที่สองนี้เป็นข้อบกพร่องที่ร้ายแรง และฉันยังไม่เห็นคำตอบที่ดีสำหรับสิ่งนี้


มีความเป็นไปได้ที่ซ้ำกันของตัวระบุการเข้าถึงใน Python: ... ซึ่งถูกปิดเนื่องจากไม่ได้สร้างสรรค์
Frank Shearar

2
@ Frank นี่คือการถามคำถามอีกครั้งเพื่อพยายามสร้างสรรค์มากขึ้น ฉันไปแล้วและลบคำถามเดิม

@ Mark Trapp: อาตกลง ขอขอบคุณสำหรับการชี้แจง. ฉันไม่เห็นวิธียกเลิกการลงคะแนนให้ปิด
Frank Shearar

@ Frank มันจะแก่ตัวเอง
Adam Lear

ปัญหาที่เกิดขึ้นprivate def whateverคือclass x: def whatever(self): passมันเป็นทางลัดclass x: pass; x.whatever = lambda self: passดังนั้นโดยพื้นฐานแล้วคุณจะต้องมี
โมดิฟายเออร์

คำตอบ:


22

"ชัดเจนดีกว่าโดยนัย" เป็นเพียงหนึ่งใน maxims ในปรัชญาการออกแบบของ Python "ง่ายดีกว่าซับซ้อน" ก็มีเช่นกัน และถึงแม้ว่ามันจะไม่ได้อยู่ใน Zen of Python แต่ "เราทุกคนยินยอมผู้ใหญ่ที่นี่" ก็เป็นอีกคนหนึ่ง

กฎข้อที่สองนั้นอาจสำคัญที่สุดที่นี่ เมื่อฉันออกแบบชั้นเรียนฉันมีความคิดว่าจะใช้อย่างไร แต่ฉันไม่สามารถทำนายการใช้ที่เป็นไปได้ทั้งหมด มันอาจเป็นไปได้ว่าบางคนใช้งานในอนาคตของรหัสของฉันจะต้องเข้าถึงตัวแปรที่ผมเคยคิดว่าเป็นเรื่องส่วนตัว ทำไมฉันต้องทำให้มันยาก - หรือเป็นไปไม่ได้เลยที่จะเข้าถึงสิ่งเหล่านี้หากโปรแกรมเมอร์ในอนาคต (หรือในอนาคตฉัน) ต้องการมัน? สิ่งที่ดีที่สุดที่ควรทำคือทำเครื่องหมายคำเตือน - ตามที่ Joonas โน้ตคำนำหน้าขีดล่างเดียวคือมาตรฐาน - ซึ่งเป็นคำที่อยู่ภายในและอาจมีการเปลี่ยนแปลง แต่ห้ามการเข้าถึงโดยสิ้นเชิงดูเหมือนไม่จำเป็น


1
"ง่ายกว่าดีกว่าซับซ้อน" และ "เราทุกคนยินยอมผู้ใหญ่ที่นี่" เป็นสาเหตุที่ Smalltalk ไม่มีตัวดัดแปลงการเข้าถึง การวางวิธีการในหมวดหมู่ "ส่วนตัว" เป็นคำใบ้ที่คุณควรคิดสามครั้งก่อนใช้และไม่ต้องเพิ่มเติม
Frank Shearar

@ Frank: "การวางวิธีการในหมวดหมู่" ส่วนตัว "เป็นคำใบ้ที่คุณควรคิดสามครั้งก่อนที่จะใช้และไม่มาก" สำหรับฉันมันก็หมายความว่าฉันไม่ต้องกังวลกับมันเมื่อฉันไม่ได้จัดการ กับมัน
เวกเตอร์

8
มีเหตุผลที่ดีที่ห้ามมิให้สมาชิกส่วนบุคคลเข้ามา: เพราะอาจทำให้ผู้เรียนคงที่ได้ หากคุณไม่สามารถเขียนสมาชิกส่วนตัวคุณจะไม่สามารถมั่นใจได้ว่าชั้นเรียนของคุณทำงานอย่างถูกต้อง
svick

7
"ทำไมฉันถึงทำให้มันยาก - หรือเป็นไปไม่ได้เลยที่จะเข้าถึงสิ่งเหล่านี้หากโปรแกรมเมอร์ในอนาคต (หรือในอนาคตฉัน) ต้องการมัน?" เพราะหนึ่งในหลักการพื้นฐานของการออกแบบคือการแยกระหว่างส่วนต่อประสาน (สิ่งที่ชิ้นส่วนของรหัสให้) และการนำไปใช้ (วิธีที่จะให้มัน) Encapsulation ทำหน้าที่ลดความซับซ้อนของรหัสโดยลดการพึ่งพาระหว่างส่วนต่าง ๆ ของรหัส ดังนั้นสาธารณะและส่วนตัวถูกใช้อย่างถูกต้องเพื่อจุดประสงค์ในการรักษารหัสให้ง่ายขึ้นโดยอนุญาตให้เห็นเฉพาะสิ่งที่จำเป็น
Giorgio

3
ไม่สามารถ diagree เพิ่มเติมได้ Access modifiers ส่งเสริมแนวคิดที่เข้าใจดีที่สุดสองข้อในการลดความซับซ้อนในซอฟต์แวร์ขนาดใหญ่: การห่อหุ้มและแยกความกังวล การไม่ให้บริการทั้งสองอย่างนั้นหมายความว่าหลามไม่ใช่ภาษา OOP ที่ดีหรือไม่เหมาะสมที่จะสร้างซอฟต์แวร์ขนาดใหญ่และไม่มีอะไรผิดปกติ แต่เพียงแค่ขาดคุณสมบัติดังกล่าวด้วยข้อโต้แย้งทั่วไปของนักอดิเรกเช่น "ทำไมต้องเพิ่มความซับซ้อนเมื่อไม่ต้องการ?" มันผิด
Daniel Shin

10

ฉันสงสัยว่าสาเหตุหลักของการดัดแปลงที่ขาดหายไปคือความเรียบง่าย

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

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

class ActiveRow(object):
    def __init__(self, **kwargs):
        for name, value in kwargs.items():
            setattr(self, name, value)

วิธีการจดบันทึกการเข้าถึง?

ฉันเดาว่านี่เป็นการแลกเปลี่ยน หากคุณไม่สามารถอยู่กับมันได้อย่างเคร่งครัดฉันขอแนะนำทับทิมซึ่งมีระดับนามธรรมและความคล้ายคลึงกัน แต่มีรูปแบบวัตถุที่อนุญาตให้ปรับเปลี่ยนการเข้าถึงได้


8
ฉันคิดว่ามันถูกต้อง แต่ IMO มันแย่มาก สำหรับภาษาที่ใช้ความสง่างามและความสามารถในการอ่านเป็นจุดขายที่เขียนว่า __method__ นั้นเป็นรูปลักษณ์ที่ชั่วร้ายและดูถูก
jiggy

2
นั่นไม่ใช่แบบแผน__x__คือ 'เวทมนต์' (เช่นวิธีการที่ถูกเรียกเพื่อเปิดใช้งานการรวมภาษาเช่นตัวดำเนินการโอเวอร์โหลดความสามารถในการทำซ้ำ ฯลฯ ) _xการประชุมคือ
keppla

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

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

5
@jiggy: "ฉันพยายามอย่างหนักที่จะชอบมัน" ฉันลองมา 2 ปีแล้วก็ยอมแพ้ :-( ดูเหมือนจะเป็นภาษาสคริปต์ที่ถูกแฮ็กให้ทำงานเหมือนกับภาษา OOP จริง ๆ ฉันไม่สามารถจินตนาการถึงการเขียนแอพขนาดใหญ่ที่ซับซ้อนใน Python ที่ได้รับการออกแบบและอ่านได้ดีอย่างที่คุณพูดว่า 'คุณใช้ความพยายามมากขึ้น 10 เท่า การบำรุงรักษาโค้ดมากกว่าการสร้างมัน 'OOP แบบง่าย ๆ และแนวคิดความปลอดภัยแบบพิมพ์ต้องใช้การแฮ็กและการแก้ปัญหาอย่างบ้าคลั่ง
เวกเตอร์

8

การประชุม Python นั้นจะใช้คำนำหน้าขีดล่างสำหรับสมาชิกที่ได้รับการปกป้อง / ส่วนตัว

เมื่อปฏิบัติตามอนุสัญญานี้จะมีประสิทธิภาพเหมือนกับ access modifiers ยกเว้น 1) คุณจะเห็นโดยตรงจากชื่อของสมาชิกไม่ว่าจะเป็นสาธารณะหรือไม่และ 2) คุณสามารถแบ่ง "encapsulation" ถ้าคุณต้องการ ในการทดสอบเช่นในภาษาอื่น ๆ ที่คุณจะต้องใช้การสะท้อนกลับ == รหัสเพิ่มเติม)

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


2
"ถ้าคุณสามารถทำสิ่งเดียวกัน (มีความยืดหยุ่นเพิ่มขึ้นเล็กน้อย) โดยไม่มีคำหลักพิเศษภาษาจะเล็กลงและรหัสจะกระชับขึ้น" ในความคิดของฉันโดยทั่วไปไม่เป็นความจริง (ถึงแม้ว่าจะสามารถเป็นจริงกับกรณีพิเศษของการปรับเปลี่ยนการเข้าถึง)
BenjaminB
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.