Vì những người trong các bình luận ở đây và trong hai câu hỏi khác được đánh dấu là các dup đều tỏ ra bối rối về điều này theo cùng một cách, tôi nghĩ rằng đáng để thêm một câu trả lời bổ sung trên đầu của Alex Coventry .
Việc Alex đang gán một giá trị của một loại có thể thay đổi, như danh sách, không liên quan gì đến việc mọi thứ có được chia sẻ hay không. Chúng ta có thể thấy điều này với id
chức năng hoặc is
toán tử:
>>> class A: foo = object()
>>> a, b = A(), A()
>>> a.foo is b.foo
True
>>> class A:
... def __init__(self): self.foo = object()
>>> a, b = A(), A()
>>> a.foo is b.foo
False
(Nếu bạn đang tự hỏi tại sao tôi lại sử dụng object()
thay vì, nói, 5
đó là để tránh gặp phải hai vấn đề khác mà tôi không muốn giải quyết ở đây; vì hai lý do khác nhau, những thứ hoàn toàn riêng biệt 5
có thể trở thành cùng một thể hiện của số 5
. Nhưng s hoàn toàn được tạo riêng biệt object()
không thể.)
Vậy, tại sao a.foo.append(5)
trong ví dụ của Alex lại ảnh hưởng b.foo
, nhưng a.foo = 5
trong ví dụ của tôi thì không? Vâng, hãy thử a.foo = 5
trong ví dụ của Alex, và thông báo rằng nó không ảnh hưởng b.foo
có một trong hai .
a.foo = 5
chỉ là làm cho a.foo
một tên cho 5
. Điều đó không ảnh hưởng b.foo
hoặc bất kỳ tên nào khác cho giá trị cũ a.foo
được sử dụng để đề cập đến. * Có một chút khó khăn khi chúng ta tạo một thuộc tính cá thể ẩn thuộc tính lớp, ** nhưng khi bạn nhận được điều đó, không có gì phức tạp xảy ra ở đây
Hy vọng rằng bây giờ rõ ràng lý do tại sao Alex sử dụng một danh sách: thực tế là bạn có thể thay đổi danh sách có nghĩa là dễ dàng hơn để hiển thị rằng hai biến có cùng danh sách và cũng có nghĩa là nó quan trọng hơn trong mã thực tế để biết bạn có hai danh sách hay không hai tên cho cùng một danh sách.
* Sự nhầm lẫn cho những người đến từ một ngôn ngữ như C ++ là trong Python, các giá trị không được lưu trữ trong các biến. Các giá trị sống trong đất giá trị, theo cách riêng của chúng, các biến chỉ là tên của các giá trị và việc gán chỉ tạo một tên mới cho một giá trị. Nếu nó có ích, hãy nghĩ về mỗi biến Python là một shared_ptr<T>
thay vì a T
.
** Một số người tận dụng lợi thế này bằng cách sử dụng thuộc tính lớp làm "giá trị mặc định" cho thuộc tính thể hiện mà các thể hiện có thể hoặc không thể đặt. Điều này có thể hữu ích trong một số trường hợp, nhưng nó cũng có thể gây nhầm lẫn, vì vậy hãy cẩn thận với nó.