Để hỗ trợ việc gán thuộc tính tùy ý, một đối tượng cần có __dict__: một dict liên kết với đối tượng, nơi các thuộc tính tùy ý có thể được lưu trữ. Nếu không, không có nơi nào để đặt các thuộc tính mới.
Một thể hiện của objectkhông không mang theo một __dict__- nếu nó đã làm, trước khi vấn đề phụ thuộc tròn khủng khiếp (vì dict, giống như hầu hết mọi thứ khác, thừa hưởng từ object;-), điều này sẽ yên mỗi đối tượng trong Python với một dict, trong đó sẽ có nghĩa là một overhead của nhiều byte cho mỗi đối tượng mà hiện không có hoặc cần một dict (về cơ bản, tất cả các đối tượng mà không có tùy tiện thuộc tính chuyển nhượng không có hoặc cần một dict).
Ví dụ, bằng cách sử dụng pymplerdự án xuất sắc (bạn có thể lấy nó qua svn từ đây ), chúng tôi có thể thực hiện một số phép đo ...:
>>> from pympler import asizeof
>>> asizeof.asizeof({})
144
>>> asizeof.asizeof(23)
16
Bạn sẽ không muốn mọi thứ intchiếm 144 byte thay vì chỉ 16, phải không? -)
Bây giờ, khi bạn tạo một lớp (kế thừa từ bất cứ thứ gì), mọi thứ sẽ thay đổi ...:
>>> class dint(int): pass
...
>>> asizeof.asizeof(dint(23))
184
... những __dict__ là hiện nay gia tăng (cộng, một chút chi phí hơn) - do đó, một dintví dụ có thể có các thuộc tính tùy ý, nhưng bạn phải trả khá một chi phí không gian cho sự linh hoạt đó.
Vậy nếu bạn muốn ints chỉ với một thuộc tính bổ sung foobar...? Đó là một nhu cầu hiếm hoi, nhưng Python cung cấp một cơ chế đặc biệt cho mục đích ...
>>> class fint(int):
... __slots__ = 'foobar',
... def __init__(self, x): self.foobar=x+100
...
>>> asizeof.asizeof(fint(23))
80
... không hoàn toàn nhỏ như một int, phiền bạn! (hoặc thậm chí hai ints, một cái selfvà một cái self.foobar- cái thứ hai có thể được gán lại), nhưng chắc chắn tốt hơn nhiều so với a dint.
Khi lớp có __slots__thuộc tính đặc biệt (một chuỗi các chuỗi), thì classcâu lệnh (chính xác hơn là siêu kính mặc định, type) không trang bị cho mọi cá thể của lớp đó một __dict__(và do đó khả năng có các thuộc tính tùy ý), chỉ là một , tập hợp các "khe" cứng nhắc (về cơ bản là các vị trí mà mỗi vị trí có thể chứa một tham chiếu đến một số đối tượng) với các tên đã cho.
Để đổi lấy sự linh hoạt bị mất, bạn nhận được rất nhiều byte cho mỗi phiên bản (có thể chỉ có ý nghĩa nếu bạn có nhiều phiên bản liên quan xung quanh, nhưng, có những trường hợp sử dụng cho điều đó).
objectLoại là bất biến và không thể thêm thuộc tính mới? Điều này có vẻ như nó sẽ có ý nghĩa nhất.