Yanıtlar:
Bu mükemmel bir soru.
Anahtar görüş, tuples'ın içindeki nesnelerin değiştirilebilir olup olmadığını bilmenin bir yolu olmadığıdır. Bir nesneyi değişken hale getiren tek şey, verilerini değiştiren bir yönteme sahip olmaktır. Genel olarak, bunu tespit etmenin bir yolu yoktur.
Bir başka fikir, Python'un kaplarının aslında hiçbir şey içermediğidir. Bunun yerine, diğer nesnelere referanslar tutarlar. Benzer şekilde, Python'un değişkenleri derlenmiş dillerdeki değişkenlere benzemez; bunun yerine değişken adları, yalnızca karşılık gelen bir nesneyle ilişkilendirildikleri ad alanı sözlüğündeki anahtarlardır. Ned Batchhelder bunu blog yazısında güzelce açıklıyor . Her iki durumda da, nesneler yalnızca referans sayılarını bilir; bu referansların ne olduğunu bilmiyorlar (değişkenler, kaplar veya Python içleri).
Birlikte, bu iki içgörü gizeminizi açıklar (altta yatan liste değiştiğinde neden bir liste "içeren" değişmez bir demet değişir). Aslında, demet değişmedi (daha önce yaptığı diğer nesnelere hala aynı referanslar var). Tuple değişemedi (mutasyon yöntemleri olmadığı için). Liste değiştiğinde, grup değişiklik hakkında bilgilendirilmedi (liste bir değişken, bir grup veya başka bir liste tarafından atıfta bulunulup edilmediğini bilmiyor).
Konudayken, tuple'lerin ne olduğu, nasıl çalıştıkları ve amaçlanan kullanımları hakkında zihinsel modelinizi tamamlamanıza yardımcı olacak birkaç düşünce daha:
Tuples, değişmezlikleri ile daha az ve amaçlanan amaçları ile karakterize edilir.
Tuples, Python'un heterojen bilgi parçalarını tek bir çatı altında toplamanın yoludur. Örneğin
s = ('www.python.org', 80)
, ana bilgisayar / bağlantı noktası çiftinin bir soket, bileşik bir nesne olarak iletilebilmesi için bir dize ve bir sayı bir araya getirir. Bu ışıktan bakıldığında, değiştirilebilir bileşenlere sahip olmak son derece makul.
Değişmezlik, başka bir özellik, hashabilite ile el ele gider . Ancak hasha edilebilirlik mutlak bir özellik değildir. Grubun bileşenlerinden biri yıkanamazsa, toplam demet de yıkanamaz. Örneğin, t = ('red', [10, 20, 30])
yıkanamaz.
Son örnek, bir dize ve bir liste içeren 2 parçayı gösterir. Demet kendisi değiştirilemez (yani içeriğini değiştirmek için herhangi bir yöntemi yoktur). Benzer şekilde, dize değişmezdir, çünkü dizelerde herhangi bir mutasyon yöntemi yoktur. Liste nesnesinin mutasyon yöntemleri vardır, bu nedenle değiştirilebilir. Bu, değişebilirliğin bir nesne türünün bir özelliği olduğunu gösterir - bazı nesnelerin mutasyon yöntemleri vardır ve bazılarında yoktur. Bu sadece nesneler iç içe geçtiği için değişmez.
İki şeyi hatırla. Birincisi, değişmezlik sihir değildir - sadece mutasyon yöntemlerinin olmamasıdır. İkincisi, nesneler hangi değişkenlerin veya kapların kendilerine atıfta bulunduğunu bilmez - sadece referans sayısını bilirler.
Umarım bu sizin için yararlı oldu :-)
hash()
her şey çünkü bundan devralır nesne () alt sınıfları açıkça kapatılır? karma ihtiyaç böylece hashable ve. 2) Karışabilirlik değişmezliği garanti etmez - değiştirilebilir olan yıkanabilir nesnelerden örnekler yapmak kolaydır. 3) Tuples, Python'daki çoğu kap gibi, altta yatan nesneye referans verir - onları denetleme ve onlar hakkında çıkarım yapma görevi yoktur.
Demetler en Çünkü yok listeleri, dizeleri veya numaraları içerir. Diğer nesnelere referanslar içerirler . 1 Bir demet içerdiği referansların sırasını değiştirememek, bu referanslarla ilişkili nesneleri değiştiremeyeceğiniz anlamına gelmez. 2
1. Nesneler, değerler ve tipler (bakınız: ikinci - son paragraf)
2. Standart tip hiyerarşisi (bakınız: "Değişmez diziler")
Her şeyden önce, "değişmez" kelimesi farklı insanlar için birçok farklı anlama gelebilir. Özellikle Eric Lippert'in blog yazısında değişmezliği nasıl sınıflandırdığını seviyorum . Orada, bu tür değişmezlikleri listeler:
Bunlar daha da fazla değişmezlik yapmak için çeşitli şekillerde birleştirilebilir ve eminim daha çok var. Değiştirilemez nesnelerin sadece diğer değişmez nesneleri içerebildiği derin (geçişli olarak da bilinir) değişmezlikle ilgilendiğiniz tür değişmezlik.
Bunun kilit noktası, derin değişmezliğin birçok çeşit değişmezlikten sadece biri olmasıdır. "Değişmez" kavramınızın muhtemelen bir başkasının "değişmez" kavramından farklı olduğunu bildiğiniz sürece, hangi türden birini tercih ederseniz edinebilirsiniz.
Anladığım kadarıyla, bu sorunun tasarım kararları hakkında bir soru olarak yeniden ifade edilmesi gerekiyor: Python tasarımcıları neden değiştirilebilir nesneler içerebilen değişmez bir dizi türü oluşturmayı seçti?
Bu soruyu cevaplamak için, tuple'lerin hizmet ettiği amaca dair düşünmeliyiz : hızlı , genel amaçlı diziler olarak hizmet ederler . Bunu akılda tutarak, tupllerin neden değişmez olduğu, ancak değiştirilebilir nesneler içerebileceği oldukça açık hale gelir. Zekâ için:
Tuples hızlı ve bellek verimlidir: Tuples oluşturmak için listelerden daha hızlıdır, çünkü değişmezler. Bağlanabilirlik, tuple'lerin sabit olarak oluşturulabileceği ve sabit katlama kullanılarak bu şekilde yüklenebileceği anlamına gelir . Aynı zamanda daha hızlı ve daha verimli bellekli overallocation gerek yoktur çünkü Onlar biraz konum, vb oluşturmak için demektir yavaş (benim makinede en az) açmak için hızlı tekrar rasgele öğe erişim için listelerine göre, ancak. Eğer tuples değişebilir olsaydı, bunlar gibi amaçlar için hızlı olmazlardı.
Tupler genel amaçlıdır : Tuples'ın herhangi bir nesne içerebilmesi gerekir. Değişken uzunluklu argüman listeleri ( *
işlev tanımlarındaki operatör aracılığıyla ) gibi şeyleri (hızlı bir şekilde) yapmaya alışkındırlar . Eğer tuples değişebilir nesneleri tutamazsa, böyle şeyler için işe yaramazlardı. Python, muhtemelen işleri yavaşlatacak ve kesinlikle daha az bellek verimli olacak listeler kullanmak zorunda kalacaktı.
Gördüğünüz gibi, amaçlarını yerine getirmek için, tupller değişmez olmalı , aynı zamanda değiştirilebilir nesneler de içerebilmelidir. Python tasarımcıları, içerdiği tüm nesnelerin de değişmez olduğunu garanti eden değişmez bir nesne yaratmak isteselerdi, üçüncü bir dizi türü oluşturmak zorunda kalacaklardı. Kazanç ekstra karmaşıklığa değmez.
id
Öğelerini değiştiremezsiniz . Bu yüzden her zaman aynı öğeleri içerecektir.
$ python
>>> t = (1, [2, 3])
>>> id(t[1])
12371368
>>> t[1].append(4)
>>> id(t[1])
12371368
Burada bir kol çıkmak ve burada ilgili kısmı bir liste içeriğini veya bir nesnenin durumunu değiştirebilir ederken, bir başlığın içinde içerdiğini olduğunu söylerim, değil değişim şu şekildedir o nesneye veya liste orada. Eğer boş olsa bile, bir şeyin [3] bir liste olmasına bağlı olan bir şeyiniz varsa, bunun yararlı olduğunu görebiliyordum.
Bunun bir nedeni, Python'da değişebilir bir türü değişmez bir türe dönüştürmenin genel bir yolu olmamasıdır (reddedilen PEP 351'e ve neden reddedildiğine ilişkin bağlantılı tartışmaya bakın). Bu nedenle, bu kısıtlamaya sahipse, kullanıcı tarafından yaratılan herhangi bir neredeyse yıkanamayan nesne de dahil olmak üzere, çeşitli nesne türlerini tuples'e koymak imkansız olacaktır.
Sözlüklerin ve kümelerin bu kısıtlamaya sahip olmasının tek nedeni, nesnelerin dahili olarak karma tablolar olarak uygulandıkları için nesnelerin yıkanabilir olmasını gerektirmesidir. Ancak, ironik bir şekilde, sözlüklerin ve kümelerin kendilerinin değişmez (veya yıkanabilir) olmadığını unutmayın. Tuples bir nesnenin karmasını kullanmaz, bu nedenle değişebilirliği önemli değildir.
Bir demet, demetin kendisinin genişleyemediği veya küçülemeyeceği anlamında değişmezdir, içerdiği tüm öğelerin değişmez olduğu anlamına gelmez. Aksi takdirde tukeller donuktur.