เนื่องจากคนในความคิดเห็นที่นี่และในสองคำถามอื่น ๆ ทำเครื่องหมายเป็น 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
.
** บางคนใช้ประโยชน์จากสิ่งนี้โดยใช้แอตทริบิวต์คลาสเป็น "ค่าเริ่มต้น" สำหรับแอตทริบิวต์อินสแตนซ์ที่อินสแตนซ์อาจตั้งค่าหรือไม่ก็ได้ ซึ่งอาจเป็นประโยชน์ในบางกรณี แต่ก็อาจทำให้สับสนได้เช่นกันดังนั้นโปรดใช้ความระมัดระวัง