2012-07-27 27 views
5

Tôi mới dùng Python (và không biết nhiều về lập trình), nhưng tôi nhớ đọc rằng python thường không sao chép các giá trị sao cho bất kỳ câu lệnh a = b nào làm cho b trỏ tới a. Nếu tôi chạypython byRef // copy

a = 1 
b = a 
a = 2 
print(b) 

cho kết quả 1. Nếu không phải là 2?

Trả lời

10

Không, kết quả nên 1.

Hãy suy nghĩ về toán tử gán (=) như sự phân công của một tham chiếu.

a = 1 #a references the integer object 1 
b = a #b and a reference the same object 
a = 2 #a now references a new object (2) 
print b # prints 1 because you changed what a references, not b 

toàn khác biệt này thực sự là quan trọng nhất khi giao dịch với mutable các đối tượng như lists như trái ngược với bất biến đối tượng như int, floattuple.

Bây giờ xem xét đoạn mã sau:

a=[] #a references a mutable object 
b=a #b references the same mutable object 
b.append(1) #change b a little bit 
print a # [1] -- because a and b still reference the same object 
     #  which was changed via b. 
+0

cảm ơn lời giải thích đó. Tôi nghĩ với một = 2, tôi sẽ thay đổi bất cứ điều gì một chỉ là từ 1 đến 2, nhưng từ những gì bạn nói, có vẻ như tôi thay đổi nơi một trỏ đến (đến 2 thay vì 1) – user1266138

+0

@ user1266138 - Có. Đó là một cách thích hợp để nghĩ về nó. (mặc dù trong python chúng ta thường nói "tham chiếu" như trái ngược với "điểm", nhưng đó thực sự chỉ là ngữ nghĩa). – mgilson

3

Khi bạn thực hiện b = a, nó làm cho b tham khảo các giá trị cùng một đề cập đến. Sau đó, khi bạn thực hiện a = 2, nó làm cho một tham chiếu đến một giá trị mới. b không bị ảnh hưởng.

Các quy tắc về phân công bằng Python:

  1. Phân chỉ đơn giản là làm cho tên tham khảo các giá trị.

  2. Chuyển nhượng tên không bao giờ ảnh hưởng đến các tên khác tham chiếu đến giá trị cũ.

  3. Dữ liệu không bao giờ được sao chép hoàn toàn.

0

Bạn có thể thấy những gì bạn đang mong đợi chỉ với một thay đổi nhỏ. Hai biến thực sự bắt đầu chỉ ra cùng một đối tượng, và nếu đối tượng đó có thể thay đổi, bạn có thể thấy sự thay đổi ở cả hai vị trí cùng một lúc.

>>> a = [1] 
>>> b = a 
>>> a[0] = 2 
>>> print b 
[2] 

gì bạn đã làm với ví dụ của bạn là để thay đổi a để nó không còn gọi các đối tượng 1 nhưng thay vào đó là đối tượng 2. Phần còn lại b vẫn đề cập đến số 1.

2

@mgilson có số lượng lớn answer nhưng tôi thấy khó nắm bắt hơn. Tôi đang đặt câu trả lời này như một nỗ lực để giải thích nó theo một cách khác.

a = 1 # This makes a point to a location in memory where the Integer(1) is located 
b = a # This makes b point to the same place. 
a = 2 # This makes a point to a different location in memory where Integer(2) is located 
print(b) # b still points to the place where Integer(1) was stored, so it prints out 1. 
+0

cảm ơn vì đã làm rõ – user1266138