เนื่องจากคนในความคิดเห็นที่นี่และในสองคำถามอื่น ๆ ทำเครื่องหมายเป็น dups ทั้งหมดดูเหมือนจะสับสนเกี่ยวกับเรื่องนี้ในทางเดียวกันผมคิดว่ามันคุ้มค่าที่เพิ่มคำตอบเพิ่มเติมด้านบนของอเล็กซ์โคเวนทรี
ข้อเท็จจริงที่ว่าอเล็กซ์กำหนดค่าของประเภทที่ไม่แน่นอนเช่นรายการไม่มีส่วนเกี่ยวข้องกับการแชร์สิ่งต่างๆหรือไม่ เราสามารถเห็นสิ่งนี้ด้วยidฟังก์ชันหรือตัวisดำเนินการ:
>>> 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
(หากคุณสงสัยว่าทำไมฉันถึงใช้object()แทนพูด5นั่นคือเพื่อหลีกเลี่ยงการพบปัญหาอื่น ๆ อีกสองประเด็นที่ฉันไม่ต้องการเข้าที่นี่ด้วยเหตุผลสองประการที่แตกต่างกันสิ่งที่สร้างขึ้นแยกจากกันทั้งหมด5อาจกลายเป็น อินสแตนซ์เดียวกันของหมายเลข5แต่object()ไม่สามารถสร้างขึ้นแยกต่างหาก)
เหตุใดa.foo.append(5)ในตัวอย่างของ Alex จึงมีผลb.fooแต่a.foo = 5ในตัวอย่างของฉันไม่ ดีพยายามa.foo = 5ในตัวอย่างของอเล็กซ์และแจ้งให้ทราบว่ามันไม่ได้มีผลต่อการb.fooมีอย่างใดอย่างหนึ่ง
a.foo = 5เป็นเพียงการเข้าชื่อเป็นa.foo 5ที่ไม่ส่งผลกระทบb.fooหรือชื่ออื่นสำหรับค่าเก่าที่a.fooใช้อ้างถึง * เป็นเรื่องยุ่งยากเล็กน้อยที่เรากำลังสร้างแอตทริบิวต์อินสแตนซ์ที่ซ่อนแอตทริบิวต์คลาส ** แต่เมื่อคุณได้รับสิ่งนั้นก็ไม่มีอะไรซับซ้อน เกิดขึ้นที่นี่
หวังว่าตอนนี้จะชัดเจนแล้วว่าทำไม Alex ถึงใช้รายการ: การที่คุณสามารถเปลี่ยนรายการได้หมายความว่าง่ายกว่าที่จะแสดงให้เห็นว่าตัวแปรสองตัวตั้งชื่อรายการเดียวกันและยังหมายความว่ารหัสในชีวิตจริงมีความสำคัญมากกว่าที่จะทราบว่าคุณมีสองรายการหรือ สองชื่อสำหรับรายการเดียวกัน
* ความสับสนสำหรับผู้ที่มาจากภาษาเช่น C ++ คือใน Python ค่าจะไม่ถูกเก็บไว้ในตัวแปร ค่าอยู่ในมูลค่าที่ดินตัวแปรเป็นเพียงชื่อของค่าและการกำหนดค่าจะสร้างชื่อใหม่สำหรับค่า ถ้าช่วยได้ให้คิดว่าตัวแปร Python แต่ละshared_ptr<T>ตัวแทน a T.
** บางคนใช้ประโยชน์จากสิ่งนี้โดยใช้แอตทริบิวต์คลาสเป็น "ค่าเริ่มต้น" สำหรับแอตทริบิวต์อินสแตนซ์ที่อินสแตนซ์อาจตั้งค่าหรือไม่ก็ได้ ซึ่งอาจเป็นประโยชน์ในบางกรณี แต่ก็อาจทำให้สับสนได้เช่นกันดังนั้นโปรดใช้ความระมัดระวัง