2011-08-12 28 views
7

Tôi nghĩ rằng tôi bắt đầu hiểu python, nhưng tôi vẫn gặp rắc rối với một câu hỏi cơ bản. Khi nào sử dụng copy.copy?python khi sử dụng copy.copy

>>>a=5 
>>>b=a 
>>>a=6 
>>>print b 
5 

Ok hợp lý. Nhưng trong hoàn cảnh nào thì nói b=a tạo thành một loại 'liên kết' nào đó giữa a và b sao cho sửa đổi một sau đó sẽ sửa đổi b? Đây là những gì tôi không nhận được về copy.copy - không mỗi khi bạn gán một biến khác với dấu bằng chỉ cần sao chép giá trị?

+2

Chuyển nhượng bằng Python * không bao giờ * giá trị bản sao. –

Trả lời

21

Về cơ bản, b = a điểm b đến bất cứ nơi nào a điểm và không có gì khác.

Điều bạn đang hỏi là các loại có thể thay đổi. Số, chuỗi, tuples, frozensets, booleans, None, là không thay đổi. Danh sách, từ điển, bộ, bytearrays, là mutable.

Nếu tôi thực hiện một loại có thể thay đổi, giống như một list:

>>> a = [1, 2] # create an object in memory that points to 1 and 2, and point a at it 
>>> b = a  # point b to wherever a points 
>>> a[0] = 2 # change the object that a points to by pointing its first item at 2 
>>> a 
[2, 2] 
>>> b 
[2, 2] 

Họ sẽ cả hai vẫn trỏ đến cùng một mục.

tôi sẽ bình luận về mã ban đầu của bạn quá:

>>>a=5  # '5' is interned, so it already exists, point a at it in memory 
>>>b=a  # point b to wherever a points 
>>>a=6  # '6' already exists in memory, point a at it 
>>>print b # b still points at 5 because you never moved it 
5 

Bạn luôn có thể nhìn thấy nơi một cái gì đó điểm đến trong bộ nhớ bằng cách làm id(something).

>>> id(5) 
77519368 
>>> a = 5 
>>> id(a) 
77519368  # the same as what id(5) showed us, 5 is interned 
>>> b = a 
>>> id(b) 
77519368  # same again 
>>> id(6) 
77519356 
>>> a = 6 
>>> id(a) 
77519356  # same as what id(6) showed us, 6 is interned 
>>> id(b) 
77519368  # still pointing at 5.  
>>> b 
5 

Bạn sử dụng copy khi bạn muốn tạo bản sao của cấu trúc. Tuy nhiên, nó vẫn sẽ không tạo bản sao của nội dung nào đó là interned. Số này bao gồm các số nguyên nhỏ hơn 256, True, False, None, các chuỗi ngắn như a. Về cơ bản, bạn nên gần như không bao giờ sử dụng nó trừ khi bạn chắc chắn rằng bạn sẽ không bị rối tung lên bởi interning.

Hãy xem xét một ví dụ nữa, cho thấy ngay cả với loại có thể thay đổi, chỉ một biến tại một cái gì đó mới vẫn không thay đổi biến cũ:

>>> a = [1, 2] 
>>> b = a 
>>> a = a[:1] # copy the list a points to, starting with item 2, and point a at it 
>>> b   # b still points to the original list 
[1, 2] 
>>> a 
[1] 
>>> id(b) 
79367984 
>>> id(a) 
80533904 

Slicing một danh sách (bất cứ khi nào bạn sử dụng một :) làm cho một sao chép.

+0

Câu trả lời hay. Tôi luôn biết rằng các loại bất biến được sao chép theo giá trị, không phải là tham chiếu. Bây giờ tôi biết tại sao! – wbg

3

Bài tập không bao giờ sao chép. Nó chỉ liên kết đối tượng các tài liệu tham khảo a (để dính vào ví dụ) đến b. ab tham chiếu cùng một đối tượng cho đến khi bạn thay đổi liên kết của một đối tượng. Nó hữu ích để thả "biến" như một thuật ngữ, nó chỉ là một nhãn bạn đặt trên một đối tượng, một xử lý bạn có thể sử dụng để đi qua đối tượng, không có gì nhiều hơn nữa.

copy.copy không thay đổi điều này chút nào.

Nếu bạn muốn truyền bá thay đổi ngay cả đối với số hoặc chuỗi - tại đây chương trình bất biến - bạn phải quấn các số và chuỗi vào một đối tượng khác và gán nó cho ab.

Nếu bạn muốn đi theo cách khác, bạn phải sử dụng mô-đun copy, nhưng hãy nhớ đọc tài liệu. Nhưng bạn phải suy nghĩ về các đối tượng không phải là các biến số.

+3

Tôi khuyên bạn nên đọc http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables – Evpok

Các vấn đề liên quan