2012-12-03 33 views
6

Đọc mã nguồn Django mà tôi đến khi chức năng this. Đó là triển khai cho thẻ block.Tại sao đặt thuộc tính python "riêng" từ * bên ngoài * lớp?

gì tôi quan tâm là họ đang thiết lập một biến với hai dấu gạch hàng đầu (__loaded_blocks) từ ngoài sơ thẩm parser lớp (phân tích cú pháp là một thể hiện của các Parser class). Grep nhanh trong mã nguồn Django cho thấy chuỗi loaded_blocks chỉ xảy ra ở đây.

Bây giờ tôi chưa bao giờ xem xét việc sử dụng tính năng mang tên trăn trước đây, nhưng điều này sẽ có hiệu lực ẩn thuộc tính __loaded_blocks của chính mình là parser! Để đọc thuộc tính này từ phương thức parser, bạn phải sử dụng phương thức getattr(self, "__loaded_blocks").

Tôi có nghĩ rằng đây chỉ là tác dụng phụ không mong muốn và không sử dụng của tên thuộc tính đã chọn không? Hay có mục đích sâu sắc hơn về điều này?

Nói chung, tại sao bạn muốn làm một điều như vậy?

EDIT: Để làm rõ, tôi nhận thức đầy đủ rằng miễn là bạn không cố gắng truy cập vào các thuộc tính __loaded_blocks từ một phương pháp parser, nó sẽ làm việc giống như bất kỳ thuộc tính khác, và đó là trên thực tế, không phải là thuộc tính bị xé.

+2

Không mục đích, Django chỉ có mã xấu xí. – Keith

Trả lời

3

Tôi không nghĩ Tên mangling sẽ diễn ra khi bạn thêm thuộc tính bắt đầu bằng __ đến một instance

từ docs:

tên Private mangling: Khi một định rằng bản văn xảy ra trong định nghĩa lớp học bắt đầu bằng hai hoặc nhiều ký tự gạch dưới và không kết thúc bằng hai hoặc nhiều dấu gạch dưới, nó được coi là một tên riêng tư của lớp đó. Tên riêng được chuyển thành dạng dài hơn trước khi mã được tạo cho chúng. Việc chuyển đổi chèn tên lớp ở phía trước tên, với dấu gạch dưới hàng đầu bị xóa và một dấu gạch dưới đơn được chèn vào trước tên lớp. Ví dụ: số nhận dạng __spam xảy ra trong một lớp có tên Hàm sẽ là được chuyển thành Hàm _spam. Chuyển đổi này độc lập với ngữ cảnh cú pháp trong đó mã định danh được sử dụng. Nếu tên chuyển đổi cực kỳ dài (dài hơn 255 ký tự), thì việc cắt xén được xác định thực hiện có thể xảy ra. Nếu tên lớp chỉ bao gồm các dấu gạch dưới, thì không có phép chuyển đổi nào được thực hiện.

class Test: 
    pass 

test = Test() 
test.__hello = 'hii'  
test.__hello # hiii 

Mặc dù tên không đọc sai nó vẫn đánh dấu này là "tin" cho người tiêu dùng của mã

+0

Ồ, tôi nhận ra điều này. Nhưng nếu bạn đã tạo một phương thức trong 'Test' đã in thuộc tính' __hello' sau khi nó được thiết lập, nó sẽ không thể, bởi vì thực tế nó sẽ cố gắng in thuộc tính '_Test__hello'. Như tôi đã nói, một phương thức như vậy sẽ phải sử dụng 'getattr' để in thuộc tính' __hello' được đặt bên ngoài. –

+0

@ lazyr oo vâng tôi thấy những gì bạn đang nói bây giờ! họ không đọc nó từ một phương pháp và nếu họ đã đặt cược họ sẽ không tạo ra một biến với dấu gạch dưới kép ... – dm03514

Các vấn đề liên quan