6

Tôi đã viết một trình trang trí cần truy cập các biến riêng tư và tìm thấy sự khác biệt này. Bất cứ ai có thể giải thích điều này?Tên riêng "mang tên" mangling và thuộc tính lớp học vs

(Python 2.5)

đặt tên mangling công trình như mong đợi cho các thuộc tính được định nghĩa trong lớp:

thuộc tính Instance không làm việc (và đây là cách chúng ta có nghĩa vụ phải làm điều đó đúng không?)

>>> class Tester(object): 
...  def __init__(self): 
...   self.__foo = "hi" 

>>> t = Tester() 
>>> t._Tester__foo 
AttributeError: 'Tester' object has no attribute '_Tester__foo' 

PS "Thuộc tính lớp" có phải là từ thích hợp cho các thuộc tính này không? Họ không phải là tĩnh, nhưng nếu bạn thực hiện một trong những danh sách, hoặc một số loại có thể thay đổi khác, nó được chia sẻ ...

Cập nhật

Trong thực tế, ví dụ thứ hai hoạt động tốt, quá. Đó là một vấn đề phần cứng (khởi động lại đã giúp).

+2

Thuộc tính lớp là từ đúng. Và họ luôn * chia sẻ. Tính đột biến không quan trọng. Nó khá nhiều không bao giờ vấn đề, ngoại trừ khi yêu cầu nếu bạn có thể đột biến một đối tượng nhất định. – delnan

+0

Tôi có thể nuke câu hỏi này không? Hay có ai thấy giá trị trong việc giữ nó không? Tôi không thể tái tạo vấn đề ban đầu của mình. Dường như nó hoạt động như mong đợi. – Rafe

+1

Thay vào đó hãy để nó xung quanh, vì @MartijnPieters đã đi tất cả các cách để kiểm tra vấn đề trong rất nhiều bài kiểm tra Python. – jsbueno

Trả lời

9

Đó thực sự là không phải là chính xác.

Tên mangling diễn ra vào giờ tạo lớp; bất kỳ hàm nào tham chiếu đến các tên bị xáo trộn cũng được điều chỉnh.

tôi không thể tái tạo ví dụ của bạn, ít nhất là không bằng Python phiên bản 2.4, 2.5, 2.6, 3.1 và 3.2 trên máy Mac:

>>> class Tester(object): 
...  def __init__(self): 
...   self.__foo = "hi" 
... 
>>> Tester()._Tester__foo 
'hi' 
>>> Tester().__foo 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'Tester' object has no attribute '__foo' 

Nếu bạn tháo rời các chức năng bytecode bạn có thể nhìn thấy tên này đã được đọc sai cũng như:

>>> import dis 
>>> dis.dis(Tester.__init__) 
    3   0 LOAD_CONST    1 ('hi') 
       3 LOAD_FAST    0 (self) 
       6 STORE_ATTR    1 (_Tester__foo) 
       9 LOAD_CONST    0 (None) 
      12 RETURN_VALUE   

tôi đã kiểm tra các compiler sourcetất cả tên đang chạy qua Mangler, một con đường mã mà vẫn giống nhau từ năm 2002 ít nhất.

Và có, thuộc tính lớp và thuộc tính mẫu là các cụm từ chính xác. Thuộc tính lớp luôn được chia sẻ nhưng gán thành thuộc tính trên một phiên bản gán cho cá thể. Việc tắt danh sách hoặc các đối tượng có thể thay đổi khác không giống như gán thuộc tính.

+0

Cũng hoạt động với 3.2. – delnan

+0

Bạn nói đúng. Tôi không biết chuyện gì đã xảy ra ở đó. Tôi bắt đầu khởi động lại máy tính của mình, vì vậy tôi sẽ chỉ gọi nó là một vấn đề về CNTT, "Bạn đã thử tắt và bật lại chưa?" ;) – Rafe

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