2011-05-05 21 views
6

Dive into Python numaralı telefondan python'un special class methods numaralı telefonunu okuyordum ve bazı yöntemlerin garip veya tutarsız bir sözdizimine sahip gibi görünüyor. Python sözdizimi tutarsızlığı?

Eğer len() arayıp sözlük olarak birlikte tedarik edecek bu sözlükte tuşların sayısını belirlemek için, Ancak Sözlük sınıf yöntemi öğeleri()

>>> my_dictionary.items() 
[('name', 'Old Gregg'), ('Race', 'Scaly Man-Fish')] 

çağırır bir sözlükten öğeleri almak için tartışma.

>>> len(my_dictionary) 
2 

Hep len() gibi yöntemler ne olursa olsun sınıfın aslında parçası olmadığını farz onların sözdizimi verilen üzerinde ama len() aslında bir sözlük yöntem yüklenebileceği olmadığını görmek için Python içine Dive bölüm 5 okuduktan sonra bunları denilen aradı.

my_dictionary.__len__() 

Öyleyse neden böyle bir yöntem normal bir yöntem gibi değil?

my_dictionary.len() 

Bilinmeyen bir kural var mı?

cevap

12

Guido van Rossum explained it thusly:

(a) Bazı işlemler için, önek notasyonu sadece postfix daha iyi okur - önek işlemleri görseller matematikçi yardımcı gösterimler sever matematik köklü bir geleneğe sahip (ve infix!) Bir problem hakkında düşünmek. X * (a + b) gibi bir formülü x a + x b ile tekrar yazdığımızı, ham bir OO gösterimi kullanarak aynı şeyi yapmanın sakıncalığını karşılaştırın.

(b) len(x) yazan kodu okuduğumda, bir şeyin uzunluğunu istediğini biliyorum. Bu bana iki şey söyler: sonuç bir tamsayıdır ve argüman bir çeşit konteynırdır. Aksine, x.len()'u okuduğumda, x'in bir arabirimi uygulayan veya standart len() standardına sahip bir sınıftan miras alan bir çeşit kapsayıcı olduğunu bilmem gerekir. Bir eşlemeyi uygulamayan bir sınıfın bir get() veya keys() yöntemine sahip olduğu veya bir dosya olmayan bir dosyanın write() yöntemine sahip olduğu zaman karşılaştığımız karışıklığa şahit olun.

+1

Şimdiye kadar aldığım en hızlı cevap. Teşekkürler bayım. –

+0

/F'nin bu bağlantıdaki kendi açıklamasının ikinci kısmı da kavrayıcıdır. Birçok yerleşik, sınıfların sunabileceği * diğer arayüzler * açısından varsayılan uygulamalara sahiptir. Yani iter (x), örneğin, ilk olarak x .__ iter __() 'yi dener, fakat aynı zamanda x .__ len __()' ve 'x .__ getitem __ (i)' terimini de içerir. – ncoghlan

0

Java dünyasında değiliz.

bunlar ilişkili API Bunun dışında

len() --> __len__() 
str() --> __str__() 
repr() --> __repr__() 

uygulamak halinde itiraz etmek için geçerlidir Python yöntemlerin bir yeri vardır:

Neden

my_dictionary.len() 

bir yöntem olmalıdır ?

Javascript nesnelerine, boyutlarını bir yöntem kullanmaktan çok daha fazla olan doğal olan 'uzunluk' özelliğinden yararlanın. Üzgünüz, ama Java dünyasından gelen tüm saçmalıklar iyi ve diğer dillerde mevcut olmalıdır.

+0

Sanırım 'abs()' bu kategoriye de giriyor. – Blender

+0

Elbette, tüm dil referansını alıntılamadan daha fazla yöntem var :) –

1

Bu ayrım, kullanımı kaynağından ayırdığı için yararlıdır.Sözlük sınıfına bir uzantı kodlarken, dilin bir parçası olarak temel nesneye yerleştirilmiş bir şeyi geçersiz kıldığınızı bilirsiniz. Bir kapsayıcının davranış şeklini değiştirmek istiyorsanız, __len__(), __getitem__(), vb. Üzerine yazıyorsunuz demektir.

Ancak, birisinin kodu kullanıcısı olarak, bunun için endişelenmem gerek. len(my_dictionary) kullanırsam, __len__()'u uygulamak için uygun yolu bilerek bir programcıya dayanan tutarlı davranış beklerim. Oysa herkes rasgele bir my_dictionary.len() yöntemi yazabilir. Bunu bilmiyordum.

WAY için http://www.siafoo.net/article/57 alt sorgusu ile ilgili daha fazla bilgi almak için asıl sorunuzu çoğunlukla teğet (__len__() için Bölüm 2.7.1).

+0

Bunlar iyi noktalar. –

İlgili konular