SORU
13 Kasım 2011, Pazar


Python, bir yöntem yerine bir fonksiyon kullanmalıyım?

Python Zen tek şey - daha sık bir yöntemi kullanmak için zaman karşı bir fonksiyonu kullanmak için ne zaman karar verme sorun haline çalıştırmak yapmak için bir yol olması gerektiğini belirtiyor.

Hadi önemsiz bir örnek - Satranç tahtası bir nesne al. Hadi biraz şekilde tüm yasal Kral hamle gemide mevcut almalıyız demek. Satranç tahtası yazabiliriz.() get_king_moves veya get_king_moves(chess_board)?

Burada baktım bazı ilgili sorular:

Cevaplar bende büyük ölçüde sonuçsuz olmuştur

Neden Python işlevselliği (örn listesi.için bazı yöntemler kullanıyor() dizin) ama diğer fonksiyonları (len(liste) gibi)?

Büyük nedeni tarih. İşlevleri olan türleri bir grup için genel ve bu işlemler için kullanıldı hatta yöntemleri bile yoktu nesneler için çalışmak için tasarlanmıştır (örneğin Lale). Ayrıca uygun bir işlevi vardır kullandığınızda nesneler şekilsiz bir koleksiyon için uygulanan hazır olun Python işlevsel özelliklerini (() göster, Uygula() ve ark).

Yerleşik olarak aslında, len uygulama(), max(), mın() fonksiyonu aslında her türü için bir yöntem olarak uygulanması daha az kod. Bir bireysel davalar hakkında kelime oyunu olabilir ama Python bir parçası, ve böyle köklü değişiklikleri yapmak için artık çok geç. Fonksiyonları var büyük kod kırılmasını önlemek için kalır.

İlginç olsa da, yukarıda gerçekten evlat edinmeye ne kadar çok konuşmaz.

Bu geliştiriciler olurdu nedenleri - özel yöntemler ile, biri farklı bir yöntem adı, getLength gibi seçmekte özgür(), uzunluğu(), () getlength ya da ne olursa olsun. Python çok sıkı adlandırma zorlar (ortak) fonksiyonu len kullanılabilir.

Biraz daha ilginç. Al işlevleri bir anlamda o benim, arayüzleri Pythonic sürümü.

Son olarak, from Guido himself:

Arayüzleri/Yetenekleri hakkında konuşmak beni biraz düşündürdü "haydut" özel yöntem adları. Dil, diyor ki, "Bir Referans olarak sınıf özel tarafından çağrılan belirli işlemleri uygulayabilirsiniz sözdizimi (aritmetik işlemler veya subscripting ve Dilimleme gibi) özel İsimler İle yöntemlerini tanımlama." Ama tüm bu yöntemler var __len__ veya görünen __unicode__ gibi özel İsimler İle yerleşik işlevleri yararına sağlanan, yerine için sözdizimi desteği. Muhtemelen arayüzü tabanlı bir Python bu yöntemleri düzenli olarak-adlı yöntemleri bir ABC, böylece dönüşecekti __len__ olacak

class container:
  ...
  def len(self):
    raise NotImplemented

Gerçi, düşünüyorum biraz daha, anlamıyorumtümsözdizimsel operasyon sadece uygun çağırmak olmaz normalde adlı yöntem belirli bir ABC. "<", örneğin, muhtemelen çağır "object.lessthan" (belki de "comparable.lessthan"). Başka bir çok fayda Python bu işten vazgeçirmek için yeteneği olacaktır -adı karıştırılmış bana HCI bir iyileşme görünüyor tuhaflık,.

Hm. Katılıyorum emin değilim (şu şekil :-).

"Açıklamak isterim ki "Python gerekçe her iki bit vardır ilk.

Öncelikle, len(x) x üzerine seçtim.() len HCI sebep (def __len__() çok sonra geldi). Aslında iç içe geçmiş iki nedeni vardır, hem de HCI:

(a) bazı işlemler İçin, önek gösterimi sadece daha iyi okur postfix -- prefix (ve telkin!) işlemler uzun bir geleneği var görsel yardım nerede gösterimler seven matematik matematikçi bir sorun hakkında düşünme. Hangi ile kolay karşılaştırın bu x*a x*b x*(a b) gibi bir formül sakarlık yeniden aynı şey çiğ OO kullanarak yapıyor gösterimde.

(b) kod okuduğumda diyor ki len(x)biliyorumsoran olduğunu bir şey uzunluğu. Bu bana iki şey anlatıyor: bir sonuç. tamsayı argüman tür kap. Aksine, x.len(), x bir tür olduğunu zaten biliyorum ben okuduğumda kapsayıcı bir sınıf, bu arabirim ya da bir miras uygulanması standart 16* *vardır. Tanığımız zaman zaman zaman karışıklık bir eşleme uygulama olmayan bir sınıf get() keys() bir dosya değil mi bu yöntemi, ya da bir şey write() bir yöntemi vardır.

Başka bir şekilde aynı şeyi söylüyor, ben 'len' bir yerleşik olarak görmek operasyon. O kaybetmekten nefret ediyorum. Söylediklerinde ciddi olup olmadığından emin değilim, ama 'def len(self): ...' kesinlikle sesleri gibi sıradan bir yönteme indirgemek istiyorum. Bunu şiddetle -1 ediyorum.

Python mantığı ben ikinci bit nedeni açıklamak için söz verdi __special__ ve sadece bakmak için özel bir yöntem seçtim special. Sınıflar isteyebilirsiniz operasyonların çok tahmin ediyordum geçersiz kılmak için, bazı standart (örneğin __add__ __getitem__), bazı kadar standart uzun zaman C hiç destek almadılar için (örneğin __reduce__ turşu hiç kod). Bu özel operasyon sıradan kullanmak istemedim yöntem adları, önceden varolan bir sınıf, ya da sınıflar tarafından yazılmış çünkü kullanıcılar tüm özel yöntemler için ansiklopedik bir bellek olmadan, yanlışlıkla demek istemediler işlemleri tanımlamak için sorumlu olacak muhtemelen yıkıcı sonuçları ile uygulamak. Ivan Krstić sonra geldi, onun mesajı, daha kısa ve öz anlatmış bu kadar yazılmış.

-- --Guido van (giriş sayfası: http://www.python.org/~guido/) Rossum

Bu benim anlayış bazı durumlarda, önek gösterimi sadece daha mantıklı (yani, Ördek.yapar.ördek(Duck) bir dilsel gelen vak açısından daha mantıklı.) ve yine, bu işlevler için izin ver "" arabirimleri.

Böyle bir durumda, benim tahminim Guido ilk noktada get_king_moves sadece temel uygulamak olurdu. Ama hala söylemek ile ilgili sorular açık, benzer bir itme ile yığın ve kuyruk bir sınıf uygulanması ve yöntemleri, işlevleri veya yöntemleri olmalıdır? pop bırakır (burada gerçekten push-pop bir arabirim işaret etmek istiyorum çünkü işlevleri tahmin ediyorum)

TLDR: biri vs fonksiyonu yöntemleri kullanmak, karar vermek için stratejinin ne olması gerektiğini açıklayabilir mi?

CEVAP
13 Kasım 2011, Pazar


Benim genel kural bubu işlem nesne tarafından nesne ya da yapılır?

eğer nesne tarafından yapılırsa, üye bir operasyon olmalı. Eğer başka şeyler için de geçerli olabilir, ya da başka bir şey tarafından yapılır nesneye sonra bir fonksiyon (ya da belki başka bir üyesi) olmalıdır.

Programlama tanıtırken, geleneksel (uygulama yanlış da olsa) arabalar gibi gerçek dünya nesneleri açısından nesneleri tanımlamak için. Ördek söz, Peki öyle olsun.

class duck: 
    def __init__(self):pass
    def eat(self, o): pass 
    def crap(self) : pass
    def die(self)
    ....

"Nesneler" benzerlik, "nesne yapabilirim. her şey için bir sınıf yöntemi eklemek için" doğru, gerçek olan şeyler bağlamında Bir ördek öldürmek istiyorum ki, bir eklerim .() öldürmek ördek için? Hayır... hayvanlar intihar değil bildiğim kadarıyla. Eğer bir ördek öldürmek istiyorsam, bu nedenle bunu yapmak zorundayım

def kill(o):
    if o is duck:
        o.die()
    elif o is dog:
        print "WHY????"
        o.die()
    elif o is nyancat:
        raise Exception("NYAN "*9001)
    else:
       print "can't kill it."

Bu benzetme uzaklaşmakta, neden yöntemleri ve sınıfları kullanacağız? Veri içeriyor ve umarım bizim kod yapısı bir şekilde yeniden kullanılabilir ve gelecekte genişletilebilir olması gibi istiyoruz çünkü. Bu tasarım OO için çok değerli olan saklama kavramı için bize getiriyor.

Saklama Müdür bu ne aşağı gelir gerçekten; bir tasarımcı olarak erişebilirsiniz. kesinlikle mutlaka her kullanıcı için bir uygulama ve sınıf iç ya da diğer geliştirici hakkında her şeyi gizlemelisin Sınıfları ile başa çıkmak için, bu azaltır "operasyon çok önemlibu örneği". Eğer bir operasyon örneği belirli ise, o zaman bir üye işlevi olmamalı.

TL;DR: @ne dedi Bryan. Bir örnek üzerinde çalışır ve sınıf örneği için dahili bir veri erişimi gerekiyorsa, bir üye işlev olmalıdır.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • GALERNAYA20

    GALERNAYA20

    19 NİSAN 2011
  • HBO

    HBO

    17 Mayıs 2006
  • Matthew Smith

    Matthew Smit

    24 Mayıs 2010