Neden “benliğe” ihtiyacınız var. Python örnek değişkenleri başvurmak için?


13

Java, Ruby, Haskell ve Python gibi birçok dile program yapıyorum. Üzerinde çalıştığım farklı projeler nedeniyle günde birçok dil arasında geçiş yapmam gerekiyor. Şimdi, sorun genellikle selfPython işlev tanımlarında aynı parametre üzerinde aynı yöntem çağırma yöntemleri ile ilk parametre olarak yazmayı unutma .

Bununla birlikte, Python'un bu yaklaşımına oldukça şaşırdım. Temel olarak, işleri yapmak için daha fazla yazmamız gerekiyor, Java ve Ruby gibi dillerde mevcut nesne içindeki değişkenlere otomatik olarak atıfta bulunarak basitleştiriliyor.

Sorum şu: bu neden selfgerekli? Tamamen bir stil seçimi mi, yoksa Python'un selfJava ve C ++ 'ın atlamasına izin verememesinin bir nedeni var thismı?



1
@gnat şimdi sadece artıları ve ciddiye bu iyi bir soru birkaç gün beri beni rahatsız ediyor, lütfen aşağı oylama ile öldürmeyin.
vivek

2
Bu soru stackoverflow.com/questions/2709821/… tarafından kapsamlı bir şekilde ele alınmıştır .
David Arno

Anladığım kadarıyla, ilk argüman olarak bir yapıya bir işaretçi geçirmenin C stiline dayanıyor.
Dannnno

@staticmethodYöntem bildiriminden önce yazma , hatayı bastırır (sadece bilgi için ve ayrıca önerilmez)
Yash

Yanıtlar:


23

1) selfYöntem imzalarında neden açık parametre olarak gereklidir?

Çünkü yöntemler foo.bar(baz)işlevlidir ve sadece sözdizimsel şekerdir bar(foo, baz). Sınıflar sadece bazı değerlerin fonksiyon olduğu sözlüklerdir. (Yapıcılar da sadece işlevlerdir, bu yüzden Python'a ihtiyaç duymazlar new) Python'un nesnelerin daha basit bileşenlerden oluşturulduğunu açıkça ifade ettiğini söyleyebilirsiniz. Bu "açık, örtük olmaktan daha iyidir" felsefesine uygundur.

Buna karşılık, Java'da nesneler gerçekten büyülüdür ve dildeki daha basit bileşenlere indirgenemez. Java'da (en azından Java 8'e kadar) bir işlev her zaman bir nesnenin sahip olduğu bir yöntemdir ve bu sahiplik dilin statik doğası nedeniyle değiştirilemez. Bu nedenle neye thisatıfta bulunduğu konusunda bir belirsizlik yoktur , bu nedenle dolaylı olarak tanımlanması mantıklıdır.

JavaScript, thisJava gibi örtük olan ancak işlevlerin Python'daki nesnelerden ayrı olarak var olabileceği bir dile örnektir . Bu , işlevler farklı bağlamlarda aktarıldığında ve çağrıldığında neye işaret ettiği konusunda çok karışıklığa yol açar this. Çoğu içgüdüsel olarak düşünmek this, işlevin bazı içsel özelliklerine atıfta bulunurken, aslında tamamen işlevin çağrılmasıyla belirlenir. thisPython gibi açık bir parametre olarak sahip olmak bu çok daha az kafa karıştırıcı olur inanıyorum .

Açık selfparametrenin diğer bazı faydaları :

  • Dekoratörler sadece diğer işlevleri saran işlevlerdir. Yöntemler sadece işlevler olduğundan, dekoratörler yöntemlerde iyi çalışır. Bir tür örtülü benlik olsaydı, dekoratörler yöntemlerde şeffaf bir şekilde çalışmazlardı.

  • Sınıf yöntemleri ve statik yöntemler bir örnek parametresi almaz. Sınıf yöntemleri bir sınıfı ilk argüman olarak alır (genellikle denir cls). Açık selfveya clsparametreler, neler olup bittiğini ve yöntemde nelere erişebildiğinizi çok daha net hale getirir.

2) Örnek değişkenleri neden daima "ile nitelendirilmelidir self.? "

Java'da üye değişkenlere " this." öneki eklemeniz gerekmez , ancak Python " self." da her zaman gereklidir. Bunun nedeni, Python'un değişkenleri bildirmek için açık bir sözdizimine sahip olmamasıdır, bu nedenle x = 7yeni bir yerel değişken bildirmesi veya bir üye değişkene ataması gerekip gerekmediğini anlamanın bir yolu yoktur . Belirtmek self.bu belirsizliği çözer.


Örtülü üye değişken başvurusu ( self.Java gibi) temel olarak kapsam belirleme kurallarıyla uyumsuzdur ve orada açık olmanız gerektiğinde, parametre hakkında örtük olmak artık bu kadar anlamlı değildir.
Jan Hudec

@ JanHudec: Güzel, nokta. Cevaba ekledim.
JacquesB

6

AFAIK'ın siteler arası kopyada veya burada gerçekten dokunulmamasının oldukça basit bir nedeni var: Python prosedürel bir dil olarak başladı. Aynı zamanda prosedürel bir dil olan ABC'ye dayanıyordu.

Daha sonra Nesne Yönelimi eklendi ve eklendiğinde Guido van Rossum, Python'un tasarımını basit tutmak için mümkün olan en az miktarda özellik eklemek istedi. Python zaten dicts ve işlevlere sahipti , öyleyse neden bir nesne sadece dictyuvalardan biri ve bir sınıf basitçe dictişlevlerden biri olabiliyorsa , neden dile tamamen yeni bir şey eklemelisiniz ? Bir yöntem, tek bir ayırt edici argüman üzerinde kapanan kısmen uygulanan bir işlev olarak yorumlanabilir. Python'da yöntemler tam olarak bu şekilde uygulanır: öyle değildir. Bunlar sadece ekstra bir argüman alan işlevlerdir.


Python'un OO'yu desteklediğine ve ilk yayınlanan versiyondan sınıflara ve mirasa sahip olduğuna inanıyorum. En azından wikipedia bana bunu söylüyor. Ancak van Rossums, başlangıçta dili tasarlama sürecini sizin tarif ettiğiniz gibi olabilir.
JacquesB


Bağlantı için teşekkür ederim, bu gerçekten ilginç bir okuma.
JacquesB

2

Yukarıdaki cevaplara ve Guido'nun bu konudaki kendi çatışmasını okumaya dayanan sonuçlarım :

Büyük fikir

Fonksiyonlar Python'daki önemli yapı taşlarıdır (ya da sadece bir tane söylemeliyiz), aslında fonksiyonları kullanarak OOP'yi taklit ediyoruz.

Bir sınıfın işlevler sözlüğünden başka bir şey olmadığı göz önüne alındığında, herhangi bir işlevi çalışma zamanında herhangi bir sınıfa ekleyebiliriz. Temelde bu ihtiyaç nedeniyle çalışma zamanında fonksiyonları atmak için Maymun Yamalama gibi şeyler yapabiliriz . Burada selfparametrik Polimorfizmi destekleyen parametre.


1
Cevabınız yüksek kaliteli bir cevap olduğunda kendinden cevaplanan sorular teşvik edilir. Cevabınızı diğer cevaplarla karşılaştırdığımda, bunu neden eklemeniz gerektiğini düşündüğünüzü merak ediyorum. Diğer cevaplar daha derinlere iner ve cevabınızın yaptıklarından daha fazla ayrıntı ekler.

1
@ GlenH7 cevap sadece referansımdı çünkü her gelip herkesin cevabını tekrar tekrar okuyamıyorum. Kalite ile ilgili olarak, bana biraz bilgi yanıltıcı olup olmadığını söyleyin. Her neyse, genellikle herhangi bir cevabı kabul etmek için 2-3 gün beklerim.
vivek

Aşağı oylama ucuz para birimi haline geliyor ve buradaki herkes anlamını bilmeden her iki eliyle de harcıyor. Birisi buraya gelirse, oylanan bu cevabın yanlış olduğunu varsaydığını görüyor musunuz?
vivek
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.