2012-07-20 7 views
10

artırmak bir dizeye başka bir değişken atama mu, o ilk devletler: Dizeler gibi değişmez veriler içinkopyalamak veya David Beazley tarafından "Python Esansiyel Başvuru" s.35 üzerinde başvuru sayısı

, Tercüman agresif programın farklı bölümleri arasındaki nesneleri paylaşır.

Ancak daha sonra aynı sayfada, böyle numaraları ve dizeleri olarak sabit nesneler için

, etkili bir kopyasını oluşturur bu görevi belirtiyor.

Ancak bu bir çelişki değil mi? Bir yandan paylaştıklarını söylüyor ama sonra kopyalandığını söylüyor.

cevap

5

etkin bir şekilde bir kopyasını oluşturur. Aslında bir kopyasını , oluşturmuyor. İki kopyaya sahip olmak ve iki ismin aynı değeri paylaşması arasındaki ana fark, ikinci durumda, bir isim ile yapılan değişikliklerin diğer ismin değerini etkilemesidir. Eğer değer mutasyona uğramazsa, bu fark ortadan kalkar, bu yüzden değişmez nesneler için, değerin kopyalanıp kopyalanmayacağı konusunda pratik bir sonuç yoktur.

hatta (örneğin id işlev veya is operatörü kullanarak) iletmenin türleri için kopya ve farklı nesneler arasındaki farkı söyleyebilir bazı köşe durumlar vardır

, ancak bu Python için yararlı olmayan gibi (iletmenin türleri yerleşik dizeler ve sayılar).

+1

Bunun için pek çok pratik sonuç var. Yaygın olarak kullanılan 'değişkeni Yok ise' deyimini düşünün ('Hiçbiri' yerleşik bir değişmez python nesnesidir ve 'nesne Yok' veya 'Yok' gibi görünüyorsa önemlidir). Prensipte aynı şeyi özel olarak ayrılmış bir dizeyle yapabilirsin. – mgilson

+0

Aslında, eğer x eğer None = 'ise x == Yok' kullanıldığında çok az pratik sonuç vardır. Sadece garip köşe durumlarında farklılık gösterirler (ör., X' tuhaf bir '__eq__' testini tanımlayan bir nesne). Dizeler ve sayılar üzerinde 'is' kullanımı için daha az pratik bir ihtiyaç vardır. Özel olarak "küme" dizeleri için "is" seçeneğine güvenmek, bu "ayar bir kenara" uygulamaya bağlı olduğu için önerilmez. – BrenBarn

+1

Bir anahtar kelime bağımsız değişkenini alıp almadığınızı kontrol etmek için 'x Yok ise:' seçeneğini kullandığınız genel durumu göz önünde bulundurun. “Hiçbiri” değerini kabul etmek istiyorsan ne olur? SENTINAL = '' yapabilirsin; def foo (arg = SENTINAL); eğer (arg SENTINAL) ise: arg = [] 'örneğin. Bu uygulamaya bağlı değildir. – mgilson

9

Python'daki bir ödev hiçbir zaman bir kopya oluşturmaz (teknik olarak örneğin bir sınıf üyesinin ataması örneğin __setattr__, özellikler veya tanımlayıcılar kullanılarak yeniden tanımlanırsa mümkündür).

foo döndü ne varsa

a = foo() 
b = a 

kopyalanamaz edilmemiştir Yani sonra

ve bunun yerine aynı nesneye işaret iki değişken a ve b var. Nesne değişmez olsun ya da olmasın farketmez. o (eğer bir değişkeni kullanarak nesneyi mutasyona ve değişikliğin diğer kullanılarak görünür olup olmadığını kontrol edemez çünkü) Bu durumda bu nedenle düşünmek serbest olup olmadığını söylemek zor ancak sabit nesneler ile

gerçekten a ve b olmayanlar şeklinde birbirini etkilemek. Bazı sabit nesneler için

da Pythonda

hem x ve y sayılardır
a = x + y 
b = x + y 

yerine yenilerini oluşturmak ve sonra eski nesneleri yeniden serbesttir (böylece toplam bir sayıdır ve değişmez) olabilir a ve b öğelerinin aynı nesneyi işaret etmesi. Böyle bir garanti olmadığına dikkat edin ... bunun yerine aynı değere sahip farklı nesnelere işaret ediyor olabilirler. Unutulmaması gereken önemli nokta, Python'un, özellikle e. copy veya deepcopy.Bu, sürprizlerden kaçınmak için değiştirilebilir nesnelerle önemli olan çok'dur. Gördüğünüz

yaygın bir deyim örneğin: Bu durumda self.pts = pts[:] yılında

class Polygon: 
    def __init__(self, pts): 
     self.pts = pts[:] 
    ... 

emin olmak için noktalarının tamamı dizisinin bir kopyasını yapmak için yerine self.pts = pts arasında kullanılır noktası listesi olmaz değişim olduğunu beklenmedik biçimde, nesne oluşturulduktan sonra yapıcıya iletilen listeye uygulanır.

+0

Bu cevabı beğeniyorum (+1) – mgilson