Tại sao không có sửa đổi truy cập rõ ràng trong Python:


28

Nếu 'rõ ràng tốt hơn ẩn', tại sao không có công cụ sửa đổi truy cập rõ ràng trong Python: Công khai, Được bảo vệ, Riêng tư, v.v.?

Tôi biết rằng ý tưởng là lập trình viên nên biết phải làm gì thông qua một gợi ý - không cần sử dụng 'sức mạnh vũ phu'. Nhưng IMO 'Đóng gói' hoặc 'che giấu thông tin' không chỉ để tránh mọi người, đó là một câu hỏi về tổ chức và cấu trúc: các lớp phát triển của bạn nên tự xác định, phạm vi và đường viền được phân định rõ ràng, giống như các hệ thống vật lý.

Ai đó có thể vui lòng giúp tôi giải thích rõ ràng về lý do tại sao các hạn chế truy cập được ngụ ý thay vì rõ ràng trong Python, một ngôn ngữ có vẻ gần như hoàn hảo?

Chỉnh sửa: Cho đến nay tôi đã thấy 3 câu trả lời được đề xuất và tôi nhận ra rằng có 2 phần cho câu hỏi của tôi:

  1. Tại sao không có từ khóa, ví dụ

    private def myFunc(): 
        dostuff....
    

    thay vì IMO xấu xí và khó gõ dấu gạch dưới. Nhưng đó không phải là điểm quan trọng.

  2. Quan trọng hơn:

    Tại sao những sửa đổi truy cập này chỉ 'đề xuất' hoặc gợi ý và không được thi hành. Sẽ khó thay đổi sau này? Rất đơn giản để thay đổi 'được bảo vệ' thành 'công khai' - và nếu bạn có một chuỗi thừa kế phức tạp gây khó khăn, bạn có một thiết kế kém - thiết kế của bạn nên được tinh chỉnh thay vì dựa vào một tính năng ngôn ngữ giúp dễ viết mã cấu trúc kém.

    Khi các công cụ sửa đổi truy cập được thi hành, mã của bạn sẽ tự động được ngăn cách - bạn BIẾT rằng các phân đoạn nhất định nằm ngoài phạm vi để bạn không phải đối phó với chúng trừ khi và khi cần thiết. Và, nếu thiết kế của bạn không tốt và bạn thấy mình liên tục di chuyển mọi thứ vào và ra khỏi các phạm vi khác nhau, ngôn ngữ có thể giúp bạn dọn dẹp hành động của mình.

Tôi yêu Python rất nhiều, tôi thấy điểm thứ 2 này là một thiếu sót nghiêm trọng. Và tôi vẫn chưa thấy một câu trả lời tốt cho việc này.


có thể trùng lặp các chỉ định truy cập trong Python: ... đã bị đóng vì không mang tính xây dựng.
Frank Shearar

2
@Frank đây là một câu hỏi lại cho câu hỏi đó để cố gắng xây dựng hơn. Tôi đã đi trước và xóa câu hỏi ban đầu.

@Mark Trapp: À. Cảm ơn bạn đã làm rõ. Tôi không thể thấy cách hủy bỏ phiếu bầu của mình.
Frank Shearar

@Frank Nó sẽ tự già đi.
Adam Lear

vấn đề với private def whatever, đó class x: def whatever(self): passlà một lối tắt cho class x: pass; x.whatever = lambda self: pass, vì vậy về cơ bản, bạn sẽ cần một bộ điều chỉnh riêng để gán
keppla

Câu trả lời:


22

"Rõ ràng là tốt hơn ngầm định" chỉ là một trong những câu châm ngôn trong triết lý thiết kế của Python. "Đơn giản là tốt hơn phức tạp" cũng có. Và, mặc dù nó không có trong Zen of Python, "Tất cả chúng ta đều đồng ý ở đây" là một người khác.

Quy tắc thứ hai có lẽ là quan trọng nhất ở đây. Khi tôi thiết kế một lớp, tôi có một số ý tưởng về cách nó sẽ được sử dụng. Nhưng tôi không thể dự đoán tất cả các cách sử dụng có thể. Có thể một số sử dụng mã trong tương lai của tôi yêu cầu quyền truy cập vào các biến mà tôi nghĩ là riêng tư. Tại sao tôi phải làm cho nó khó khăn - hoặc thậm chí là không thể - để truy cập những thứ này, nếu một lập trình viên tương lai (hoặc thậm chí là một tương lai tôi) cần chúng? Điều tốt nhất để làm là đánh dấu chúng bằng một cảnh báo - như Joonas lưu ý, một tiền tố gạch dưới duy nhất là tiêu chuẩn - rằng chúng là nội bộ và có thể thay đổi; nhưng cấm truy cập hoàn toàn có vẻ không cần thiết.


1
"Đơn giản là tốt hơn phức tạp" và "Tất cả chúng ta đều đồng ý ở đây" là lý do tại sao Smalltalk không có công cụ sửa đổi truy cập. Đặt một phương thức trong danh mục "riêng tư" là một gợi ý mà bạn nên nghĩ ba lần trước khi sử dụng nó, và không còn nữa.
Frank Shearar

@Frank: "Đặt một phương thức trong danh mục" riêng tư "là một gợi ý mà bạn nên nghĩ ba lần trước khi sử dụng nó, và không còn nữa" Đối với tôi, điều đó đơn giản có nghĩa là tôi không phải lo lắng về điều đó khi tôi không giao dịch với nó.
Vector

8
Có một lý do chính đáng tại sao cấm truy cập vào các thành viên tư nhân: bởi vì nó có thể phá vỡ bất biến lớp. Nếu bạn không thể viết thành viên riêng, thì bạn không thể chắc chắn rằng lớp của bạn cư xử đúng.
Svick

7
"Tại sao tôi phải làm cho nó khó khăn - hoặc thậm chí là không thể - để truy cập những thứ này, nếu một lập trình viên tương lai (hoặc thậm chí là một tương lai tôi) cần chúng?" Bởi vì một trong những nguyên tắc cơ bản của thiết kế là sự tách biệt giữa giao diện (những gì một đoạn mã cung cấp) và cách thực hiện (cách nó cung cấp nó). Đóng gói phục vụ để giảm độ phức tạp của mã bằng cách giảm sự phụ thuộc giữa các phần khác nhau của mã. Vì vậy, công khai và riêng tư được sử dụng chính xác cho mục đích giữ cho mã đơn giản hơn bằng cách chỉ cho phép xem những gì cần thiết.
Giorgio

3
Không thể diagree hơn. Công cụ sửa đổi truy cập thúc đẩy hai trong số các khái niệm có thể hiểu rõ nhất để giảm bớt sự phức tạp trong phần mềm lớn: Đóng gói và tách mối quan tâm. Không phục vụ cả hai điều này đơn giản có nghĩa là python không phải là ngôn ngữ OOP tốt cũng không phù hợp để xây dựng phần mềm lớn và không có gì sai với điều đó. Nhưng chứng minh sự vắng mặt của các tính năng như vậy với các đối số sở thích điển hình như "Tại sao lại thêm sự phức tạp khi không cần thiết?" chỉ là sai.
Daniel Shin

10

Tôi nghi ngờ lý do chính cho việc sửa đổi truy cập bị thiếu là Đơn giản

Như bạn nói, đó không phải là về việc khiến mọi người tránh xa, mà là về tổ chức, vì vậy điểm chính của 'riêng tư' là, nó sẽ gửi một thông điệp tới người dùng api của bạn 'vui lòng không viết mã phụ thuộc vào điều này'.

Không nên nói 'theo quy ước, không nên sử dụng _x hoặc __x bên ngoài lớp', nhưng trong mô hình đối tượng động của python, thật khó để đưa ra một ký hiệu.

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

Làm thế nào để lưu ý khả năng truy cập?

Tôi đoán, đây là một sự đánh đổi. Nếu bạn hoàn toàn không thể sống với nó, tôi sẽ đề xuất ruby, có mức độ trừu tượng và năng động tương tự, nhưng có một mô hình đối tượng, cho phép sửa đổi truy cập.


8
Tôi nghĩ điều này là chính xác, nhưng IMO, nó thật tồi tệ. Đối với một ngôn ngữ sử dụng sự tao nhã và dễ đọc như việc bán các điểm viết __method__ trông khá ghê tởm và khó hiểu.
nhảy lên

2
đó không phải là quy ước, __x__là 'ma thuật', (tức là các phương thức được gọi để cho phép tích hợp ngôn ngữ như quá tải toán tử, khả năng lặp lại, v.v.). Quy ước là _x.
keppla

6
Xin lỗi, tôi vẫn đang loay hoay với Python. Tôi đang cố gắng hết sức để thích nó, nhưng những thứ như thế này khiến tôi hơi bực mình. Đặc biệt là bây giờ tôi cần nhớ ý nghĩa của một phương thức có bao nhiêu dấu gạch dưới. Theo quan điểm của OP, dường như các sửa đổi rõ ràng sẽ rõ ràng hơn. Sự can thiệp là tuyệt vời, nhưng nó không thể thổi phồng sự rõ ràng. Bạn dành 10 lần nỗ lực để duy trì mã hơn là xây dựng nó.
nhảy lên

2
Ví dụ của tôi không có nghĩa là hiển thị số lượng khác nhau của dấu gạch dưới, việc sử dụng __init__là ngẫu nhiên. Ví dụ đặt một số thuộc tính của đối tượng, không biết về thời gian biên dịch, vì vậy một công cụ sửa đổi truy cập rõ ràng sẽ không giúp bạn.
keppla

5
@jiggy: "Tôi đang rất cố gắng để thích nó". Tôi đã cố gắng trong 2 năm - rồi bỏ cuộc. :-( Xuất hiện là một ngôn ngữ kịch bản đã bị hack để hành xử hơi giống ngôn ngữ OOP thực sự. Tôi không thể tưởng tượng việc viết một ứng dụng lớn, phức tạp bằng Python được thiết kế tốt và có thể đọc được. Như bạn đã nói 'Bạn tốn nhiều gấp 10 lần duy trì mã hơn là xây dựng nó '. OOP đơn giản và gõ các khái niệm an toàn đòi hỏi phải có các bản hack và cách giải quyết điên rồ.
Vector

8

Quy ước Python là sử dụng tiền tố gạch dưới cho các thành viên được bảo vệ / riêng tư.

Công ước này, khi theo sau, là có hiệu quả tương tự như bổ truy cập, ngoại trừ 1), bạn sẽ thấy trực tiếp từ nhân viên tên cho dù đó là công hay không, và 2), bạn có thể phá vỡ "đóng gói" nếu bạn thực sự muốn (điều này có thể chính đáng trong ví dụ kiểm tra, trong một số ngôn ngữ khác, bạn sẽ phải sử dụng sự phản chiếu == thêm mã).

Cuối cùng, đó là một câu hỏi về hương vị, nhưng nếu bạn có thể làm điều tương tự (với sự linh hoạt hơn một chút) mà không có từ khóa đặc biệt, ngôn ngữ sẽ nhỏ hơn và mã sẽ ngắn gọn hơn, nói chung là một điều tốt.


2
"Nếu bạn có thể làm điều tương tự (với sự linh hoạt hơn một chút) mà không có từ khóa đặc biệt, ngôn ngữ sẽ nhỏ hơn và mã sẽ ngắn gọn hơn" Theo tôi, điều này thường không đúng. (Ngay cả khi điều đó có thể đúng với trường hợp đặc biệt của công cụ sửa đổi truy cập)
BenjaminB
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.