Ý nghĩa của __ dict __ trong python là gì?

Hầu hết mọi người chỉ biết một điều khi nói đến quyền truy cập thuộc tính – dấu chấm ‘. ’ [như trong

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

5]. Nói một cách đơn giản, truy cập thuộc tính là cách bạn truy xuất một đối tượng được liên kết với đối tượng bạn đã có. Đối với những người sử dụng Python mà không đi sâu vào chi tiết, nó có vẻ khá đơn giản. Tuy nhiên, đằng sau đó, có rất nhiều điều xảy ra đối với nhiệm vụ có vẻ tầm thường này

Hãy xem xét từng thành phần một

Thuộc tính __dict__

Mọi đối tượng trong Python đều có một thuộc tính được ký hiệu là

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

6. Đối tượng từ điển/giống như từ điển này [tôi sẽ giải thích điều này ngay sau đây] chứa tất cả các thuộc tính được xác định cho chính đối tượng đó. Nó ánh xạ tên thuộc tính thành giá trị của nó

Đây là một ví dụ

>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

Lưu ý cách

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

7 không có trong
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

8. Lý do cho điều này là đủ đơn giản. Trong khi
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

9 được định nghĩa cho đối tượng
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

0, thì
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

1 được định nghĩa cho lớp của nó [
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

2]. Do đó, nó sẽ xuất hiện trong
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

6 của
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

2. Trên thực tế,
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

6 của
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

2 cũng chứa rất nhiều khóa khác [bao gồm cả
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

7]

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

Chúng ta sẽ sớm xem xét ý nghĩa của

>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

8

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

6 của một đối tượng đủ đơn giản để hiểu. Nó hoạt động giống như Python
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

70 và cũng là một

>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

Tuy nhiên,

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

6 của một lớp không đơn giản như vậy. Nó thực sự là một đối tượng của lớp có tên là 
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

8.
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

8 là một lớp đặc biệt có các đối tượng hoạt động giống như những lớp
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

70 bình thường, nhưng chúng khác nhau ở một số hành vi chính

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

7

Lưu ý cách bạn không thể đặt khóa trực tiếp trong

>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

8 [_______176 không hoạt động]. Tuy nhiên, bạn có thể thực hiện điều tương tự bằng cách sử dụng
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

77, vì hành vi bên trong sau đó khác. Cũng lưu ý cách bạn không thể tự đặt thuộc tính
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

6 [
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

79 không hoạt động]

Có một lý do đằng sau việc thực hiện kỳ ​​lạ này. Nếu bạn không muốn tìm hiểu chi tiết, chỉ cần biết rằng trình thông dịch Python tiếp tục hoạt động bình thường và thực thi một số tối ưu hóa. Nếu bạn muốn giải thích chi tiết hơn, hãy xem câu trả lời của Scott H cho câu hỏi StackOverflow này

mô tả

Bộ mô tả là một đối tượng có ít nhất một trong các phương thức ma thuật sau trong các thuộc tính của nó.

>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

90,
>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

91 hoặc
>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

92 [Hãy nhớ rằng, các phương thức cuối cùng là các đối tượng trong Python]. Tâm trí bạn, đó là đối tượng chúng ta đang nói về. Lớp của nó có thể hoặc có thể đã triển khai chúng

Các bộ mô tả có thể giúp bạn xác định hành vi của một thuộc tính đối tượng trong Python. Với mỗi phương pháp ma thuật vừa được đề cập, bạn thực hiện cách thuộc tính ['được mô tả' bởi bộ mô tả] sẽ được truy xuất, thiết lập và xóa trong đối tượng tương ứng. Có hai loại bộ mô tả - Bộ mô tả dữ liệu và Bộ mô tả phi dữ liệu

Bộ mô tả phi dữ liệu chỉ có

>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

90 được xác định. Tất cả những thứ khác là Mô tả dữ liệu. Bạn sẽ tự nhiên nghĩ, tại sao hai loại này lại được gọi như vậy. Câu trả lời là trực quan. Thông thường, các thuộc tính liên quan đến dữ liệu của nó mà chúng ta có xu hướng 'đặt' hoặc 'xóa' đối với một đối tượng. Các thuộc tính khác, chẳng hạn như bản thân các phương thức, chúng tôi không. Vì vậy, bộ mô tả của chúng được gọi là Bộ mô tả phi dữ liệu. Cũng như nhiều thứ khác trong Python, đây không phải là một quy tắc khó và nhanh, mà là một quy ước. Bạn cũng có thể mô tả một phương thức với Bộ mô tả dữ liệu. Nhưng sau đó,
>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

90 của nó sẽ trả về một hàm

Đây là một ví dụ về hai lớp sẽ đưa ra các đối tượng mô tả dữ liệu và phi dữ liệu tương ứng

>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

9

Lưu ý cách hàm

>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

90 nhận một đối tượng
>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

96 và [của nó] lớp
>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

97. Tương tự, việc đặt giá trị yêu cầu
>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

96 và một số ứng cử viên
>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

99. Xóa chỉ cần
>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

96. Đưa các tham số này vào [cùng với trình khởi tạo
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

11] giúp bạn phân biệt giữa các đối tượng của cùng một lớp mô tả. Xin lưu ý bạn, đó là các đối tượng được dùng để mô tả.
[P. S. Nếu bạn không định nghĩa phương thức
>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

90 cho một bộ mô tả, thì chính đối tượng bộ mô tả đó sẽ được trả về].

Hãy sử dụng các lớp này trong một số mã

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

1

Đó là nó. Bạn có thể truy cập các đối tượng 'được mô tả' như bình thường trong Python

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

4

Các bộ mô tả được sử dụng cho rất nhiều chức năng liên quan đến thuộc tính và phương thức trong Python, bao gồm các phương thức tĩnh, phương thức lớp và thuộc tính. Sử dụng bộ mô tả, bạn có thể kiểm soát tốt hơn cách truy cập các thuộc tính và phương thức của một lớp/đối tượng của nó – bao gồm cả việc xác định một số chức năng 'đằng sau hậu trường' như ghi nhật ký

Bây giờ, hãy xem các quy tắc cấp cao quản lý quyền truy cập thuộc tính trong Python

Các quy tắc

Trích dẫn nguyên văn cuốn sách của Shalabh Chaturvedi, quy trình làm việc như sau

  1. Nếu
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    13 là một đặc biệt [i. e. thuộc tính do Python cung cấp] cho
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    14, trả lại nó
  2. Kiểm tra
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    15 cho
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    13. Nếu nó tồn tại và là một bộ mô tả dữ liệu, hãy trả về kết quả của bộ mô tả. Tìm kiếm tất cả các cơ sở của
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    17 cho cùng một trường hợp
  3. Kiểm tra
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    18 cho
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    13 và trả lại nếu tìm thấy. Nếu
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    14 là một lớp, hãy tìm cả cơ sở của nó. Nếu nó là một lớp và một bộ mô tả tồn tại trong nó hoặc các cơ sở của nó, hãy trả về kết quả của bộ mô tả
  4. Kiểm tra
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    15 cho
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    13. Nếu nó tồn tại và là một bộ mô tả phi dữ liệu, hãy trả về kết quả của bộ mô tả. Nếu nó tồn tại và không phải là một bộ mô tả, chỉ cần trả lại nó. Nếu nó tồn tại và là một bộ mô tả dữ liệu, thì chúng ta không nên ở đây vì chúng ta đã quay lại điểm 2. Tìm kiếm tất cả các cơ sở của
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    17 cho cùng một trường hợp
  5. Nâng cao
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    44

 

Để làm cho mọi thứ rõ ràng hơn, đây là một số sửa đổi bằng cách sử dụng mã mà chúng tôi đã viết trong phần Mô tả [Hãy xem lại nó để hiểu rõ hơn về mọi thứ]

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

45 là một bộ mô tả dữ liệu trong lớp của
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

46. Vì vậy, bạn không thể viết trên nó. Ngoài ra, phiên bản trong
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

47 ['desc3'] được sử dụng, không phải phiên bản trong
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

48

>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

1

Nguyên vẹn, ngay cả khi bạn thực hiện một mục thích hợp trong chính tả của

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

46, nó vẫn không thành vấn đề [theo Quy tắc 1]

>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

3

Mặt khác, thuộc tính Non-Data Descriptor có thể dễ dàng ghi đè

>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

4

Tuy nhiên, bạn có thể thay đổi hành vi của

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

45, nếu bạn vào lớp của
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

46 và sửa đổi nó trong chính dictproxy ở đó

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

0

Lưu ý thời điểm bạn thay thế Bộ mô tả dữ liệu trong lớp bằng một số bộ mô tả phi dữ liệu [hoặc một số đối tượng như Chuỗi trong trường hợp này], mục nhập mà chúng tôi đã tạo ban đầu trong

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

6 của
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

46 sẽ phát huy tác dụng. Do đó,
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

14 trả về
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

15, không phải
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

16

Thuộc tính

>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

17 hoạt động tương tự như
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

45

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

1

Lưu ý cách bạn có thể 'ghi đè' ________ 617 trong chính ________ 447. Sau khi bạn làm điều đó, chúng ta sẽ xem qua Quy tắc 1-2-3 và dừng lại ở 4, để có kết quả là

>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

15

Quy tắc đặt thuộc tính

Cách đơn giản hơn các quy tắc để 'lấy chúng'. Trích dẫn lại cuốn sách của Shalabh,

  1. Kiểm tra
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    15 cho
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    13. Nếu nó tồn tại và là bộ mô tả dữ liệu , hãy sử dụng bộ mô tả để đặt giá trị. Tìm kiếm tất cả các cơ sở của
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    17 cho cùng một trường hợp.
  2. Chèn
    >>> c.__dict__
    {'y': 5}
    >>> c.__dict__.__class__
    
    >>> c.__dict__ = {}
    >>> c.y
    
    Traceback [most recent call last]:
      File "", line 1, in 
        c.y
    AttributeError: 'C' object has no attribute 'y'
    >>> c.__dict__['y'] = 5
    >>> c.y
    5
    
    
    35 vào
    >>> c.__class__.__dict__['x']
    4
    >>> c.__class__.__dict__
    dict_proxy[{'__dict__': , 'x': 4, 
    '__module__': '__main__', '__weakref__': , 
    '__doc__': None}]
    
    
    18 cho khóa
    >>> c.__dict__
    {'y': 5}
    >>> c.__dict__.__class__
    
    >>> c.__dict__ = {}
    >>> c.y
    
    Traceback [most recent call last]:
      File "", line 1, in 
        c.y
    AttributeError: 'C' object has no attribute 'y'
    >>> c.__dict__['y'] = 5
    >>> c.y
    5
    
    
    37

Đó là nó. . -]

__slots__

Nói một cách ngắn gọn,

>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

38 là một cách để không cho phép các đối tượng có
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

6 của riêng chúng trong Python. Điều này có nghĩa là nếu bạn định nghĩa
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

38 trong một Lớp, thì bạn không thể đặt các thuộc tính tùy ý [ngoài các thuộc tính được đề cập trong 'khe'] trên các đối tượng của nó

Đây là một ví dụ về một lớp như vậy

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

2

Bây giờ hãy xem điều này hoạt động như thế nào

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

3

tất nhiên bạn có thể làm điều này

>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

4

Nhưng sau đó, hãy nhớ rằng bạn hiện đã định nghĩa

>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

41 trong
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

6 của
>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

42, không phải trong
>>> class C[object]:
	x = 4

>>> c = C[]
>>> c.y = 5
>>> c.__dict__
{'y': 5}

96

Như chính Guido van Rossum đã đề cập trong bài đăng trên blog của mình,

>>> c.__dict__
{'y': 5}
>>> c.__dict__.__class__

>>> c.__dict__ = {}
>>> c.y

Traceback [most recent call last]:
  File "", line 1, in 
    c.y
AttributeError: 'C' object has no attribute 'y'
>>> c.__dict__['y'] = 5
>>> c.y
5

38 đã được triển khai bằng Python để mang lại hiệu quả, chứ không phải cài đặt thuộc tính 'khắt khe'. Trực giác cơ bản là thế này. Giả sử bạn có một lớp mà bạn định xây dựng một số lượng lớn các đối tượng. Bạn không thực sự cần sự linh hoạt khi có các thuộc tính 'động' trên chính các đối tượng, nhưng bạn muốn hiệu quả. Vì các vị trí về cơ bản loại bỏ thuộc tính
>>> c.__class__.__dict__['x']
4
>>> c.__class__.__dict__
dict_proxy[{'__dict__': , 'x': 4, 
'__module__': '__main__', '__weakref__': , 
'__doc__': None}]

6 trong mỗi đối tượng, nên bạn sẽ tiết kiệm được rất nhiều bộ nhớ theo cách này

Thật thú vị, các vị trí được triển khai bằng cách sử dụng bộ mô tả trong Python

 

Đọc thêm

Hãy xem cuốn sách này tôi đã trích dẫn trong bài viết. Nó đi sâu vào rất nhiều chi tiết liên quan đến quyền truy cập thuộc tính trong Python, bao gồm cả độ phân giải phương thức

__ TRỰC TIẾP __ Python là gì?

dir[] trong Python . ] a powerful inbuilt function in Python3, which returns list of the attributes and methods of any object [say functions , modules, strings, lists, dictionaries etc.]

Hàm dict[] là gì?

Hàm dict[] tạo từ điển . Từ điển là một bộ sưu tập không có thứ tự, có thể thay đổi và lập chỉ mục.

__ lớp __ trong Python là gì?

__class__ là một thuộc tính trên đối tượng đề cập đến lớp mà đối tượng được tạo ra từ đó . một. __lớp__ # Đầu ra.

Thuộc tính dict Python là gì?

AttrDict , Từ điển thuộc tính, giống hoàn toàn với dict gốc của python , ngoại trừ trong hầu hết các trường hợp, bạn có thể sử dụng khóa từ điển . Điều này cho phép người dùng tạo các đối tượng vùng chứa trông như thể chúng là các đối tượng lớp [miễn là người dùng phản đối các giới hạn phù hợp].

Chủ Đề