2015-11-13 35 views
7

Python'daki modül düzeyi sabit yineleme listeleri yerine tupl'leri kullanmak iyi bir stil midir? Benim program çalışırkenTuples, Python'daki modül seviyesi sabitleri için listelerden mi?

IMPORTANT_STRINGS = [ 
    "Hello world!", 
    "Goodbye world!", 
    "Foo...", 
    # etc --- there are about 40 entries 
] 

IMPORTANT_STRINGS modifiye asla: Örneğin, benim girişte aramak gerekir dosyama üstündeki önemli dizeleri bir listesi var. Bir taraftan, immutabilitenin iyi olduğunu ve mümkün olduğunda değişmez veri yapılarını tercih etmem gerektiğini düşündüğümden, bunun yerine bir tuple kullanmalıyım.

Diğer yandan, bu tupllerin sadece değişmez listelerden daha fazlası olduğunu düşünüyorum: onlar çiftler, üçlüler, vs. gibi şeyleri geçtiğinizde kullanılması gereken heterojen koleksiyonlar için --- sabit boyutlu şeyler büyüklüğü ne oldukları için önemlidir. Ben de hiç böyle sabitleri için dizilerini kullanan vahşi Python kodunu gördüğüm sanmıyorum ve bunu söylemek bana göze gerçekten tuhaf görünüyor:

IMPORTANT_STRINGS = (
    "Hello world!", 
    etc 
) 
+2

sabir değişmezlik anlamına gelir, bu yüzden şahsen bir tuple kullanacağım ... bunun için tanımlanmış “en iyi uygulama” olmadığını gayet iyi biliyorum, bu yüzden hangisini kullanırsanız kullanın daha fazla –

+0

Bunları neden herhangi bir yapıda gruplandırıyorsunuz? herşey? Hiç onların üzerinde yinelenecek misin? Onlara hiç endeksle ulaşıyor musunuz (ve eğer öyleyse, bu gerçekten onlara ulaşmanın en iyi yolu mu?) Neden dize sabitlerini tanımlıyorsunuz? Genelde dize sabitleri uzun koleksiyonları sadece bana kötü bir kod gibi görünüyor, gerçekten istediğiniz bir nesne üzerinde bir tür öznitelik ya da anahtar kelime argümanları olurdu. [Yazılı bir kod] (http://c2.com/cgi/wiki?StringlyTyped) bir belirtisi olma eğilimindedir. – ArtOfWarfare

+0

Zehirli olarak - listeler aynı türdeki tüm nesnelerden oluşmalıdır. Tupllerin böyle bir kısıtlaması yoktur - farklı tiplerde nesneler olabilir veya olmayabilir. Ancak değişkeniniz "IMPORTANT_STRINGS" olarak adlandırıldığından, kullanıcı için koleksiyonun türü ne olursa olsun, "string" türünde olan değerlerin oldukça açık olduğunu düşünüyorum. – ArtOfWarfare

cevap

4

Bir modül oluşturun, aşağıdaki foo.py ve insert çağrı , FOO, tuple, orijinal haliyle foo modülünde kanonik toplama olarak kalır. Diğer taraftan BAR, mutasyona uğrayabilir.

Hangisini tercih etmelisiniz?

Diğer modüller koleksiyona eriştiğinde ne yapmak istediğinize bağlıdır. Birçok durumda, diğer modüllerin bir kanonik listeye ekleyebilmesini istiyoruz. Bazı durumlarda, yapmayız. Cevap, koşullarınız ve amaçlarınız ve tasarım ve kullanım amaçlı niyetlerinize uygun olanı yapmaktır. Senin durumunda

diyorsunuz: benim program çalışırken

ÖNEMLİ İPLERİ değiştirilemez asla.onlar modifiye edilmelidir hiçbir zaman

sonra küpe iyidir. Kodunuzun aynı süreçte veri paylaşması gerekebilecek başkalarına yararlı olmasını istiyorsanız, bir listeyle birlikte gitmelisiniz.

Sen söz:

Ben küpe sadece değişmez listeleri daha fazlası olduğunu düşünüyorum: onlar çiftleri gibi şeyler etrafında geçen yaparken kullanılması gereken heterojen koleksiyonları, triple vb konum --- boyutları ne oldukları için önemli olan sabit boyutlu şeyler.

Çok fazla heterojenliğe yakalanamazdım. Tupler esasen değişmez listelerdir ve listelerde de her türlü nesne bulunabilir. Evet, sabit boyut, ama bu gerçekten değişmezlikten doğrudan bir sonuç.

Listelerin yukarıda gösterildiği gibi tuplerle genişletilebilme yeteneğinin, genellikle tupllerle başlayabileceğiniz ve daha sonra gerektiği gibi listelere taşıyabileceğiniz anlamına geldiğini unutmayın. from <module> import * kullanılır:
+0

Değişken ve değişmez veri yapıları arasındaki farkı ve neden değişmez olanları tercih etmem gerektiğini anlıyorum. Sadece kendimden vazgeçtim çünkü python'u böyle yazmamıştım --- eğer sadece mutabiliteye ihtiyaç duyduğumda listeler kullansaydım, şu an kullandığım koleksiyonların yaklaşık% 80'i yerine tuples kullanırdım.Gerçekten sadece tamamen gerekli olduğunda listeleri kullanarak, neredeyse tamamen tuple dolu kod yazıyor musunuz? –

+0

@PatrickCollins Kendimi, diğer Python kodlayıcılarından daha çok tuple kullanarak buluyorum (tek Python dizisi olarak listelenmiş gibi görünüyor). Python'un ördek-tipi ve soyut temel sınıf kontrolünden yararlanıyorum, bunun yerine bir liste kullanmaya başlamanız gerekirse, kodumu değiştirmem gerekiyor. Benim mantığım genellikle performans açısından güvenlikten çok daha fazladır. –

+0

Bu cevabı kabul ediyorum çünkü bu en eksiksiz, ancak tatmin edici bulmuyorum. Bu davada listeler üzerinde tuple kullanan bir kod görmemiştim ve hala stilistik olarak çok garip olduğunu düşünüyorum. Python'u sürekli olarak listelerin üzerindeki tuplleri kullandığını hayal edebiliyorum ve bunun iyi olacağını düşünüyorum, ama kendi kişisel projeniz üzerinde çalışmadığınız sürece, bunun takımdaki diğer geliştiricilerin beklentileriyle çatışacağını düşünüyorum. Çekilebilirlik önemlidir ve bunu destekleyen dillerde harikadır, ancak imo bu Pythonic değildir. –

3

ben demet için gitmek istiyorum . Tuplar daha hızlı, değişmez ve bunun sebebidir - daha güvenlidir. Neden değişmez olması gereken bir şey için değişken bir tip istiyorsun?

"Koparmaların heterojen koleksiyonlar için olduğu" argümanının benim için bir anlamı yok. Listeler heterojen öğeleri de depolayabilir. Tuple = heterojen ve listeler = homojen olduğu varsayımı sadece bir genelleştirmedir, genellikle bir listeyi yinelemek ve benzer şekilde onlarla çalışmak istersiniz (eğer tam olarak aynı şekilde en azından bir polimorfik şekilde)

Tuples öte yandan, kodlama yaptığınız modelde bir miktar ilişkiye sahip olan değerleri saklamak için kullanılan anlamdaki bir yapıya biraz benzerdir ve bu şekilde heterojen elementlerle ilişkilidir, ama neden aynı tip olamaz? Mesela 3 boyutlu bir vektör bir tuple (En azından en sezgisel yol) olarak temsil edilecekti, ama sadece 3 sayıdan oluşuyordu, bir listeyi kullanmalı mıyız, aynı sebepten mi? Şimdi

FOO = 'a', 'b' 
BAR = ['a', 'b'] 

içe ve yerinde operasyonları nasıl tepki bkz:

>>> import foo 
>>> from foo import FOO, BAR 
>>> FOO += 'c', 'd' 
>>> BAR += 'c', 'd' 
>>> FOO 
('a', 'b', 'c', 'd') 
>>> foo.FOO 
('a', 'b') 
>>> foo.BAR 
['a', 'b', 'c', 'd'] 

Gördüğümüz gibi

+0

Sanırım yapmam gerekenden daha heterojen bir şekilde vurdum, fakat vektörler farklı --- onların N boyutunun olması, onların türünün içsel bir parçası. Bu yapıya sahip olmaları önemlidir. Diğer yandan, bu, çalışma zamanında oluşturulmak yerine, statik olarak başlatılan birkaç şeyin yalnızca bir koleksiyonudur. Kodun% 80'inin kazara saf olduğunu ve% 99'unun önemsiz olarak yeniden yazılabileceğini düşünüyorum. Tetikleri varsayılan koleksiyon türü olarak kullanan python kodunu hiç görmedim, böyle bir kod yazıyor musunuz? –

1

Sadece bir karşı argüman, __all__ zaman bir modül ihraç edecek kamu nesnelerin liste olduğunu.

Bu, temel olarak, modül düzeyindeki sabit dizeleri (sahip olduğunuz gibi) topluluğudur, ancak standart kitaplık boyunca bir liste olarak uygulanır. Hızlı bir test, bunun için bir tuple'un da çalışacağını doğrular, yine de her yerde bir liste.

+0

Bu bir değişiklik, modülleri yerinde genişletebileceğiniz anlamına gelir. Daha önceki Python'lardaki deneyimimden beklenen etkiyi elde etmek için bir liste olmalı, ancak Python 3 ile hızlı bir kontrol, bunun önemli olmadığını gösteriyor. –

+0

İlginç ... Modüller nasıl genişliyor? – Gerrat

+0

API'ye ekleme anlamında genişletilmiş kullanıyorum, ancak '__all__' tuple'ının yerini değiştirmek yerine (import * 'ile içe aktarılan adları etkiler) basit bir mesele olsa da, göremiyorum Herhangi bir başka bir modülün '__all__' kullanan kişi ismini doğrudan ithal ederek. –