Trước hết A.__dict__.__dict__
là khác với A.__dict__['__dict__']
, và trước đây không tồn tại. __dict__
Thuộc tính sau là thuộc tính mà các thể hiện của lớp sẽ có. Đó là một đối tượng mô tả trả về từ điển nội bộ của các thuộc tính cho phiên bản cụ thể. Tóm lại, __dict__
thuộc tính của một đối tượng không thể được lưu trữ trong đối tượng __dict__
, vì vậy nó được truy cập thông qua một bộ mô tả được xác định trong lớp.
Để hiểu điều này, bạn phải đọc tài liệu về giao thức bộ mô tả .
Phiên bản ngắn:
- Đối với một thể hiện của lớp
A
, quyền truy cập vào instance.__dict__
được cung cấp bởi A.__dict__['__dict__']
nó giống như vars(A)['__dict__']
.
- Đối với lớp A, quyền truy cập
A.__dict__
được cung cấp bởi type.__dict__['__dict__']
(trên lý thuyết) giống như vars(type)['__dict__']
.
Phiên bản dài:
Cả hai lớp và đối tượng đều cung cấp quyền truy cập vào các thuộc tính thông qua toán tử thuộc tính (được triển khai thông qua lớp hoặc siêu kính __getattribute__
) và __dict__
thuộc tính / giao thức được sử dụng bởi vars(ob)
.
Đối với các đối tượng bình thường, __dict__
đối tượng tạo một dict
đối tượng riêng biệt , lưu trữ các thuộc tính và __getattribute__
trước tiên cố gắng truy cập nó và lấy các thuộc tính từ đó (trước khi cố gắng tìm kiếm thuộc tính trong lớp bằng cách sử dụng giao thức bộ mô tả và trước khi gọi __getattr__
). Bộ __dict__
mô tả trên lớp thực hiện quyền truy cập vào từ điển này.
x.name
tương đương với cố gắng những theo thứ tự: x.__dict__['name']
, type(x).name.__get__(x, type(x))
,type(x).name
x.__dict__
làm tương tự nhưng bỏ qua cái đầu tiên vì những lý do rõ ràng
Vì nó không thể cho __dict__
các instance
phải được lưu trữ trong __dict__
các ví dụ, nó được truy cập thông qua giao thức mô tả trực tiếp thay vào đó, và được lưu trữ trong một lĩnh vực đặc biệt trong trường hợp.
Một kịch bản tương tự cũng đúng đối với các lớp, mặc dù chúng __dict__
là một đối tượng proxy đặc biệt giả vờ là một từ điển (nhưng có thể không nằm trong nội bộ) và không cho phép bạn thay đổi hoặc thay thế nó bằng một từ điển khác. Proxy này cho phép bạn, trong số tất cả những thứ khác, truy cập vào các thuộc tính của một lớp dành riêng cho nó, và không được xác định trong một trong các cơ sở của nó.
Theo mặc định, một vars(cls)
lớp trống mang ba bộ mô tả - __dict__
để lưu trữ các thuộc tính của các cá thể, __weakref__
được sử dụng nội bộ bởi weakref
và chuỗi tài liệu của lớp. Hai phần đầu tiên có thể biến mất nếu bạn xác định __slots__
. Sau đó, bạn sẽ không có __dict__
và __weakref__
thuộc tính, nhưng thay vào đó bạn sẽ có một thuộc tính lớp duy nhất cho mỗi vị trí. Các thuộc tính của cá thể sau đó sẽ không được lưu trữ trong từ điển và quyền truy cập vào chúng sẽ được cung cấp bởi các bộ mô tả tương ứng trong lớp.
Và cuối cùng, sự mâu thuẫn A.__dict__
khác với A.__dict__['__dict__']
là do thuộc tính __dict__
, ngoại lệ, không bao giờ được tra cứu vars(A)
, vì vậy những gì đúng với nó không đúng với bất kỳ thuộc tính nào khác mà bạn sử dụng. Ví dụ, A.__weakref__
là điều tương tự như A.__dict__['__weakref__']
. Nếu sự mâu thuẫn này không tồn tại, việc sử dụng A.__dict__
sẽ không hoạt động và bạn phải luôn sử dụng vars(A)
thay thế.
ive
. Ít nhất nó sẽ đã thực hiện điều này một nhiềuA.__dict__['ive']
câu hỏi;) Tôi sẽ thấy bản thân mình ra