'Benlik' kelimesinin amacı nedir?


1130

selfPython'daki kelimenin amacı nedir ? Bu sınıftan oluşturulan belirli bir nesneyi ifade ettiğini anlıyorum, ancak neden açıkça her işleve parametre olarak eklenmesi gerektiğini göremiyorum. Örneklemek gerekirse, Ruby'de bunu yapabilirim:

class myClass
    def myFunc(name)
        @name = name
    end
end

Anladığım kadarıyla, oldukça kolay. Ancak Python dahil etmek gerekir self:

class myClass:
    def myFunc(self, name):
        self.name = name

Biri benimle bu konuda konuşabilir mi? (Kuşkusuz sınırlı) deneyimime rastladığım bir şey değil.


111
Guido van Rossum'un "Neden açık benlik kalması gerekiyor" makalesini ilginç bulabilirsiniz: neopythonic.blogspot.com/2008/10/…
unutbu

14
Ayrıca bkz. "Neden" yöntem tanımlarında ve çağrılarında neden açıkça kullanılmalıdır? ": Docs.python.org/faq/…
unutbu

37
"Hangisini anlıyorum, oldukça kolay" --- Oldukça öznel, değil mi? Bundan @namedaha sezgisel yapan nedir self.name? İkincisi, IMO, daha sezgiseldir.
Noel Baba

14
Bir işlev ve bir sınıf yöntemi arasındaki temel fark budur. Bir işlev serbest, serbest. Bir sınıf (örnek) yönteminin üst öğesinin (ve üst özelliklerinin) farkında olması gerekir, bu nedenle yönteme üst sınıfa ( öz olarak ) bir başvuru iletmeniz gerekir . OOP'yi anlamadan önce içselleştirmeniz gereken daha az örtülü bir kuraldır. Diğer diller semantik basitlik üzerine sözdizimsel şekeri seçer, python diğer diller değildir.
Evan Plaice

9
"Açık, örtükten daha iyi" olduğunu düşünmüyorum, bu tasarım seçimini gerçekten iyi açıklıyor. @foove örtük bir çözüme ihtiyaç duyulmadığı self.fooiçin eşit derecede açıktır (örn. C ++ 'da, örnek üyelere ad alanları kullanılarak "açıkça" olmadan "örtük" olarak erişilebilir). Tek fark, Ruby'nin yeni bir semantik (@) tanıtması, Python'un sunmamasıdır. Yeni bir semantiğin kaçınılması gereken ayrıntı düzeyine değip değmeyeceği tamamen özneldir. Yine de, çoğu modern dilin burada bir konsept sunmayı seçtiğine dikkat edilmelidir (örn. Php's $ this, JS's).
Jing

Yanıtlar:


710

Eğer kullanımına ihtiyaç nedeni self.Python kullanmaz çünkü @örnek özelliklerine başvurmak için sözdizimi. Python yöntemi edilecek ait olduğu örneğini olacak şekilde yöntemlerini yapmaya karar geçirilen otomatik değil alınan otomatik: yöntemlerinin ilk parametre yöntemi denir örneğidir. Bu, yöntemleri işlevlerle tamamen aynı hale getirir ve gerçek adı size kullanmak için bırakır ( selfkural olmasına rağmen ve insanlar başka bir şey kullandığınızda genellikle size kaşlarını çatacaktır.) Koda selfözel değildir, sadece başka bir nesne .

Python, normal adları özniteliklerden ayırmak için başka bir şey yapabilirdi - Ruby gibi özel sözdizimi veya C ++ ve Java gibi bildirimler veya belki de daha farklı bir şey - ama olmadı. Python, her şeyi açık bir şekilde yapmak, neyin ne olduğunu açıkça ortaya koymak için ve bunu her yerde yapmasa da, örneğin nitelikler için yapıyor. Bu nedenle bir örnek niteliğine atamanın hangi örneğe atanacağını bilmesi gerekir ve bu yüzden buna ihtiyaç duyar self..


23
@Georg: clsörnek nesneyi değil, sınıf nesnesini ifade eder
SilentGhost

17
@SilentGhost: Aslında, ilk parametrenin adı olmasını istediğiniz her şeydir. Sınıf metotlarında, kural kullanmaktır clsve selfgeleneksel olarak örneğin metotlar için kullanılır. Eğer isteseydim, selfsınıf clsyöntemleri ve örneğin yöntemler için kullanabilirdim . Ben de kullanabilirsiniz bobve fnordeğer sevdim.
SingleNegationElimination

67
Topluluğun thisyerine seçim yapmamasını ilginç buluyorum self. selfEski programlama dillerinde bilmediğim bir geçmiş var mı ?
Jules GM

24
@Julius selfModula-3'ün sözleşmelerinden geldi , bu seçim hakkında daha fazla ayrıntı için bu cevaba bakınız . (Feragat: benimdir).
Bakuriu

9
@Julius selfAnahtar kelimesi (Smalltalk, 1980) thisanahtar kelimeden önce gelir (C ++ 'dan). Bakınız: stackoverflow.com/questions/1079983/…
Wes Turner

425

Basit bir vektör sınıfı alalım:

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

Uzunluğu hesaplayan bir yöntemimiz olsun istiyoruz. Sınıf içinde tanımlamak istersek nasıl olurdu?

    def length(self):
        return math.sqrt(self.x ** 2 + self.y ** 2)

Küresel bir yöntem / işlev olarak tanımlayacağımızda neye benzemeli?

def length_global(vector):
    return math.sqrt(vector.x ** 2 + vector.y ** 2)

Böylece tüm yapı aynı kalır. Bunu nasıl kullanabilirim? Bir an lengthiçin Vectorsınıfımız için bir yöntem yazmadığımızı varsayarsak , bunu yapabiliriz:

Vector.length_new = length_global
v = Vector(3, 4)
print(v.length_new()) # 5.0

İlk parametresi çünkü bu işler length_globalolarak yeniden kullanılabilir olabilir selfparametre length_new. Açık bir şekilde bu mümkün olmazdı self.


Açık olana olan ihtiyacı anlamanın bir başka yolu da selfPython'un nereye sözdizimsel şeker eklediğini görmektir. Aklınızda bulundurduğunuzda, bu temelde,

v_instance.length()

dahili olarak

Vector.length(v_instance)

Nereye selfuyduğunu görmek kolaydır . Python'da örnek yöntemler yazmazsınız; yazdığınız şey, ilk parametre olarak örneği alması gereken sınıf yöntemleridir. Bu nedenle, example parametresini açıkça bir yere yerleştirmeniz gerekir.


4
Vector.length_new = length_global ... Aslında sınıf bildirimlerimde böyle bir sözdizimi kullanmaya başladım. Ne zaman sadece bazı yöntemleri başka bir sınıftan devralmak istediğinizde, ben sadece açıkça başvuru yöntemlere kopyalayın.
Jeeyoung Kim

2
python'un "örnek yöntemi" nin, birden çok özelliği paketlemek için aktarılan bir örnek nesnesiyle statik küresel yöntemlerin (Java veya C ++ gibi) sözdizimsel bir şekeri olduğunu söylemek adil olur mu? --- peki bu yarı-doğrudur çünkü polimorfizmde, "bu" (java'da olduğu gibi) veya "benliğin" en önemli amacı, yöntemlerin doğru uygulanmasını sağlamaktır. Python'da bu var. myobj.someMethod () öğesini çağırmak python'daki TheClassOfMyObj.someMethod (myobj) öğesine eşittir. "TheClassOfMyObj" otomatik olarak "self" den python tarafından anlaşılır unutmayın, aksi takdirde bunu bulmak zorunda kalacak.
teddy teddy

3
Infact, sadece örnek yöntemler sadece sınıf yöntemleri değil, aynı zamanda yöntemlerin de Vector.length_new = length_globalgösterdiği gibi bir sınıfın üyesi olan işlevlerdir .
RussW

1
"Bu, length_global'ın ilk parametresi length_new içinde self parametresi olarak yeniden kullanılabileceğinden açık bir öz olmadan mümkün olmaz." - aynı şekilde çalışır. örtük benlik için yeniden kullanılır ... ikinci örnek dairesel bir akıl yürütmedir - kendini açıkça oraya yerleştirmelisiniz, çünkü python'un açık benliğe ihtiyacı vardır.
Karoly Horvath

1
@KarolyHorvath: Tabii ki, dahili olarak tanımlanan yöntemlerin açık bir benliğe ihtiyaç duymadığı, ancak harici olarak tanımlanan yöntemlerin gerektirdiği bir modelle bir dile sahip olmak da mümkün olacaktır. Ama her iki durumda da açık benlik gerektirme konusunda bazı tutarlılıklar olduğunu söyleyebilirim, bu da bunu bu şekilde meşru bir neden haline getirir. Diğer diller farklı yaklaşımlar seçebilir.
Debilski

422

Diyelim ki şu şekilde tanımlanmış ClassAbir yöntem içeren bir sınıfınız var methodA:

def methodA(self, arg1, arg2):
    # do something

ve ObjectAbu sınıfın bir örneğidir.

Şimdi ObjectA.methodA(arg1, arg2)çağrıldığında, python dahili olarak sizin için şu şekilde dönüştürür:

ClassA.methodA(ObjectA, arg1, arg2)

selfDeğişken nesnenin kendisine atıfta bulunmaktadır.


94
Diğer tüm cevapları okudum ve bir tür anlaşıldım, bunu okudum ve sonra mantıklı geldi.
Seth

3
Bu benim için çivilenmiş!
Bernard 'Beta Berlin' Parah

2
Neden o bağırsakları Ruby'de olduğu gibi içeride tutmuyorsunuz?
Cees Timmerman

Fakat __init __ (self) yönteminde kendini kabul eder, o zaman nesneyi yaratmadan bile, kendini nasıl ifade eder?
saurav

Cidden, bu Debilski'nin örneğinden çok daha iyi çünkü aşırı karmaşık değil ve insanlar vektörlere aşina olmayabilir.
NoName

215

Nesneler başlatıldığında, nesnenin kendisi self parametresine geçirilir.

resim açıklamasını buraya girin

Bu nedenle, nesnenin verileri nesneye bağlıdır. Aşağıda, her bir nesnenin verilerinin nasıl görünebileceğini görselleştirmek isteyebileceğinize bir örnek verilmiştir. 'Kendini' nasıl nesne adıyla değiştirdiğinize dikkat edin. Aşağıdaki bu örnek diyagramın tamamen doğru olduğunu söylemiyorum ama umarım ki kendini kullanmayı görselleştirmede bir amaca hizmet eder.

resim açıklamasını buraya girin

Nesne self parametresine iletilir, böylece nesne kendi verilerini tutabilir.

Bu tamamen doğru olmasa da, böyle bir nesneyi örnekleme işlemini düşünün: Bir nesne yapıldığında, sınıfı kendi verileri ve yöntemleri için bir şablon olarak kullanır. Kendi adını self parametresine iletmeden, sınıftaki öznitelikler ve yöntemler genel bir şablon olarak kalır ve nesneye atıfta bulunmaz (ona ait değildir). Bu nedenle, nesnenin adını self parametresine iletmek, bir nesneden 100 nesne başlatılırsa, hepsinin kendi verilerini ve yöntemlerini takip edebileceği anlamına gelir.

Aşağıdaki çizime bakın:

resim açıklamasını buraya girin


Hey, Bob'un özniteliklerine örneğin "bob.name ()" ile erişirken, aslında " init " den konuşmak için bob ().
udarH3

3
Yukarıdaki yoruma bob.name () yazdığınızda, addan sonra köşeli parantez eklediğiniz için bob'un name () adında bir yöntemi olduğunu ima edersiniz. Ancak bu örnekte böyle bir yöntem yoktur. 'bob.name' (parantez içermeyen), init (yapıcı) yönteminden name adlı özniteliğe doğrudan erişiyor. Bob'un speak yöntemi çağrıldığında, name özniteliğine erişen ve bir print deyiminde döndüren yöntemdir. Bu yardımcı olur umarım.
sw123456

3
Hayır, bob nesnesi için aslında bob.name olan self.name değerini alırsınız, çünkü nesnenin adı oluşturulurken (örneklenir) self parametresine iletilir. Yine, umarım bu yardımcı olur. Varsa ana gönderiyi oylamaktan çekinmeyin.
sw123456

2
Ad, örnekleme sırasında self.name öğesine atanır. Bir nesne oluşturulduktan sonra, nesneye ait olan tüm değişkenler 'self' ön ekine sahip olan değişkenlerdir. Sınıftan oluşturulduğunda kendiliğin nesnenin adıyla değiştirildiğini unutmayın.
sw123456

5
İşleri bu şekilde açıklıyorsunuz! güzel iş :)
penta

80

Bu örneği beğendim:

class A: 
    foo = []
a, b = A(), A()
a.foo.append(5)
b.foo
ans: [5]

class A: 
    def __init__(self): 
        self.foo = []
a, b = A(), A()
a.foo.append(5)
b.foo
ans: []

18
yani kendini olmadan vars sadece java gibi sınıfın statik vars olduğunu
teddy teddy

5
teddy teddy, tamamen doğru değilsin. Davranış (statik veya statik olmayan gibi) yalnızca selfdeğişken türüne değil, aynı zamanda değişken türüne de bağlıdır . İlk örneği liste yerine basit tamsayı ile yapmaya çalışın. Sonuç oldukça farklı olurdu.
Konstantin

2
Aslında, bununla ilgili sorum, neden a.fooilk örnekte söylemenize izin verildi A.foo? Açıkça foosınıfa ait ...
Radon Rosborough

Çoğu dilde nesnenin örneklerinden statik üyeleri çağırabilirsiniz. Bu neden şaşırtıcı?
Paarth

2
@RadonRosborough Çünkü ilk örnekte ave bher ikisi de A()(sınıf) için etiketler (veya işaretçiler ). a.foobaşvuran A().foosınıf yöntemi. İkinci örnekte, yine de, abir bir referans olur , örneğin bir A()şekilde yapar b. Şimdi bunun yerine sınıf nesnesine örnekleri olduğunu, kendini tanır fooyöntem örneklerinde çalışmasına.
LegendaryDude

40

Sınıfları kullanmayan kod ile göstereceğim :

def state_init(state):
    state['field'] = 'init'

def state_add(state, x):
    state['field'] += x

def state_mult(state, x):
    state['field'] *= x

def state_getField(state):
    return state['field']

myself = {}
state_init(myself)
state_add(myself, 'added')
state_mult(myself, 2)

print( state_getField(myself) )
#--> 'initaddedinitadded'

Sınıflar her zaman bu "durum" şeyinden geçmekten kaçınmanın bir yoludur (ve başlatma, sınıf kompozisyonu, nadiren ihtiyaç duyulan metasınıflar ve operatörleri geçersiz kılmak için özel yöntemleri destekleme gibi diğer güzel şeyler).

Şimdi yukarıdaki kodu, temelde aynı şeyi göstermek için yerleşik python sınıfı makinelerini kullanarak gösterelim.

class State(object):
    def __init__(self):
        self.field = 'init'
    def add(self, x):
        self.field += x
    def mult(self, x):
        self.field *= x

s = State()
s.add('added')    # self is implicitly passed in
s.mult(2)         # self is implicitly passed in
print( s.field )

[cevabımı yinelenen kapalı sorudan taşıdı]


1
Keşke Python, Ruby'nin yanı sıra işleyicileri de şekerle kapladı.
Cees Timmerman

20

Aşağıdaki alıntılar benlik hakkındaki Python belgelerinden alınmıştır :

Modula-3'te olduğu gibi, nesnenin üyelerini yöntemlerinden referans almak için [Python'da] herhangi bir kısayol yoktur: method işlevi, nesneyi temsil eden ve çağrı tarafından örtük olarak sağlanan açık bir ilk argümanla bildirilir.

Genellikle, bir yöntemin ilk argümanı benlik olarak adlandırılır. Bu bir konvansiyondan başka bir şey değildir: benlik adının Python için kesinlikle özel bir anlamı yoktur. Bununla birlikte, kurallara uyulmadığında, kodunuzun diğer Python programcıları tarafından daha az okunabilir olabileceğini ve ayrıca bu tür bir kurala dayanan bir sınıf tarayıcı programının yazılabileceğini aklınızda bulundurun.

Daha fazla bilgi için, sınıflarla ilgili Python belgeleri eğitimine bakın .


20

Daha önce belirtilen diğer tüm nedenlerin yanı sıra, geçersiz kılınan yöntemlere daha kolay erişim sağlar; arayabilirsiniz Class.some_method(inst).

Yararlı olduğu yere bir örnek:

class C1(object):
    def __init__(self):
         print "C1 init"

class C2(C1):
    def __init__(self): #overrides C1.__init__
        print "C2 init"
        C1.__init__(self) #but we still want C1 to init the class too
>>> C2()
"C2 init"
"C1 init"

17

Kullanımı thisJava'da anahtar kelime kullanımına benzer , yani mevcut nesneye bir referans vermek.


2
sınıf myClass: def myFunc (bu, ad): this.name = ad
LEMUEL ADANE

16

Python, Java veya C ++ 'dan farklı olarak Nesne Tabanlı Programlama için oluşturulmuş bir dil değildir.

Python'da statik bir yöntem çağrıldığında, içinde düzenli argümanları olan bir yöntem yazılır.

class Animal():
    def staticMethod():
        print "This is a static method"

Bununla birlikte, bir hayvan olan bir değişken oluşturmanızı gerektiren bir nesne yöntemi, bu durumda, kendi kendine argümana ihtiyaç duyar

class Animal():
    def objectMethod(self):
        print "This is an object method which needs an instance of a class"

Self yöntemi, sınıf içindeki değişken bir alanı belirtmek için de kullanılır.

class Animal():
    #animalName made in constructor
    def Animal(self):
        self.animalName = "";


    def getAnimalName(self):
        return self.animalName

Bu durumda, benlik tüm sınıfın animalName değişkenine atıfta bulunur. UNUTMAYIN: Bir yöntem içinde bir değişkeniniz varsa, benlik çalışmaz. Bu değişken yalnızca bu yöntem çalışırken mevcuttur. Alanları tanımlamak için (tüm sınıfın değişkenleri), bunları sınıf yöntemlerinin DIŞINDA tanımlamanız gerekir.

Söylediklerimin tek bir kelimesini anlamıyorsanız, Google "Nesneye Yönelik Programlama". Bunu anladıktan sonra, bu soruyu sormanıza bile gerek kalmayacak :).


Çünkü arasındaki ayrımın + 1 staticMethod()ve objectMethod(self). Ben bir örnek gerekiyorsa , ilk çağırmak için söyleyebilirim Animal.staticMethod(), eklemek istiyorum objectMethod():a = Animal(); a.objectMethod()
Laryx Decidua

Söylediğiniz şey% 100 doğru değil. Bu sadece bir kongre. Oluşturulan bir nesneden statik yöntemi yine de çağırabilirsiniz. Herhangi bir sınıf üyesi kullanamazsınız çünkü bir benlik beyan etmediniz. Hatta statik olmayan çağırmak için Animal.objectMethod (animalObj) çağırabilirim. Temel olarak bu, statik bir yöntemin yalnızca üye değişkenleri kullanmayan bir yöntem olduğu anlamına gelir. Kendini beyan etmeye gerek yok. Bence bu aptalca bir dil gereksinimi. Lua ve C ++ gibi diller sahne arkasında obj değişkenleri sağlar.
user441521

İşe yaramaz bir animalName dize bildirimi ve kilitlenen animalName yöntemi yaptınız.
Cees Timmerman

3
@ytpillai Alakasız. Kafa karıştırıcı ve yanlış kod cevap olarak sunulmamalıdır.
Cees Timmerman

1
def getAnimalNamedöndürmeye çalıştığınız dizeyi tıkamamak ve selfsınıfın herhangi bir alanını değil sınıf örneğini ifade eder.
Cees Timmerman

10

Python zen'i “açık, örtük olmaktan daha iyidir” izlemek için orada. Gerçekten de sınıf nesnenize bir referans. Örneğin Java ve PHP'de buna denir this.

Eğer user_type_namemodeliniz bir alandır Eğer bunu erişmek self.user_type_name.


10

Her şeyden önce, benlik geleneksel bir isimdir, yerine başka bir şey (tutarlı olarak) koyabilirsiniz.

Nesnenin kendisine atıfta bulunur, böylece onu kullanırken, .name ve .age öğesinin oluşturacağınız Student nesnelerinin (notu, Student sınıfının değil) olduğunu beyan edersiniz.

class Student:
    #called each time you create a new Student instance
    def __init__(self,name,age): #special method to initialize
        self.name=name
        self.age=age

    def __str__(self): #special method called for example when you use print
        return "Student %s is %s years old" %(self.name,self.age)

    def call(self, msg): #silly example for custom method
        return ("Hey, %s! "+msg) %self.name

#initializing two instances of the student class
bob=Student("Bob",20)
alice=Student("Alice",19)

#using them
print bob.name
print bob.age
print alice #this one only works if you define the __str__ method
print alice.call("Come here!") #notice you don't put a value for self

#you can modify attributes, like when alice ages
alice.age=20
print alice

Kod burada


1
Cevabınız benim için en açık görünüyor. +1
Pawel

9

selfnesnenin kendisine yapılan bir nesne başvurusudur, bu nedenle aynıdır. Python yöntemleri nesnenin kendisi bağlamında çağrılmaz. selfPython özel nesne modelleri veya başka bir şey ile başa çıkmak için kullanılabilir.


8

Geleneksel olarak adlandırılan argümanın kullanımını selfanlamak zor değil, neden gerekli? Veya neden açık bir şekilde bahsedelim? Sanırım, bu soruyu arayan çoğu kullanıcı için daha büyük bir soru, ya da değilse, python'u öğrenirken kesinlikle aynı soruya sahip olacaklar. Bu iki blogu okumalarını tavsiye ederim:

1: Kendini açıklayan kullanımı

Anahtar kelime olmadığını unutmayın.

İnit de dahil olmak üzere her sınıf yönteminin ilk argümanı her zaman sınıfın geçerli örneğine bir göndermedir. Kural olarak, bu argüman her zaman benlik olarak adlandırılır. İnit yönteminde, benlik yeni yaratılan nesneyi ifade eder; diğer sınıf yöntemlerinde, yöntemi çağrılan örneği ifade eder. Örneğin, aşağıdaki kod yukarıdaki kodla aynıdır.

2: Neden bu şekilde sahibiz ve neden Java gibi bir argüman olarak ortadan kaldıramıyoruz ve bunun yerine bir anahtar kelimemiz var

Eklemek istediğim başka bir şey de, isteğe bağlı bir selfargüman yazmadan bir sınıf içindeki statik yöntemleri bildirmeme izin veriyor self.

Kod örnekleri:

class MyClass():
    def staticMethod():
        print "This is a static method"

    def objectMethod(self):
        print "This is an object method which needs an instance of a class, and that is what self refers to"

Not : Bu sadece Python 3.x sürümünde çalışır.

Önceki sürümlerde, açıkça @staticmethoddekoratör eklemeniz gerekir , aksi takdirde selfargüman zorunludur.


7

Kimsenin Lua'yı yetiştirmediğine şaşırdım. Lua 'öz' değişkenini de kullanır, ancak atlanabilir ancak yine de kullanılabilir. C ++ 'this' ile aynı şeyi yapar. Her işlevde 'kendini' bildirmek için herhangi bir neden göremiyorum, ancak yine de lua ve C ++ ile yapabildiğiniz gibi kullanabilmelisiniz. Kısa olmakla övünen bir dil için, kendi değişkenini bildirmeniz gariptir.


6

Aşağıdaki örneğe bir göz atın; self

class Restaurant(object):  
    bankrupt = False

    def open_branch(self):
        if not self.bankrupt:
           print("branch opened")

#create instance1
>>> x = Restaurant()
>>> x.bankrupt
False

#create instance2
>>> y = Restaurant()
>>> y.bankrupt = True   
>>> y.bankrupt
True

>>> x.bankrupt
False  

self örnekleri arasında ayrım yapmak için kullanılır / gereklidir.

Kaynak: Python'da kendi değişkeni açıklandı - Pythontips


Evet, sanırım benliğin neden kullanıldığını biliyoruz, ancak soru şu ki, dil neden onu açıkça beyan ediyor. Diğer birçok dil buna ve kısa olmasıyla övünen bir dile ihtiyaç duymaz, size sadece Lua veya C ++ (bu) gibi kullanmak için perde arkasındaki değişkeni vereceğini düşünürsünüz.
user441521

3
@ kmario23 Yanıt buradaydı: pythontips.com/2013/08/07/the-self-variable-in-python-explained Lütfen yanıtları kendiniz olarak gönderirken her zaman orijinal yazarları onaylayın.
geekidharsh

@geekidharsh teşekkürler, bir not ekledim!
kmario23

5

Çünkü python tasarlanırken alternatifler pek işe yaramazdı. Python, yöntemlerin veya işlevlerin, örtük this(a-la Java / C ++) veya açık @(a-la ruby) işlevlerinin çalışmadığı bir bağlamda tanımlanmasına izin verecek şekilde tasarlanmıştır . Python sözleşmeleriyle açık yaklaşıma bir örnek verelim:

def fubar(x):
    self.x = x

class C:
    frob = fubar

Şimdi fubarişlev işe yaramaz çünkü selfküresel bir değişken (ve frobaynı zamanda) olduğunu varsayar . Alternatif, yöntemlerin yerine global bir kapsam ( selfnesnenin nerede olduğu) uygulamaktır.

Örtük yaklaşım,

def fubar(x)
    myX = x

class C:
    frob = fubar

Bu, myXyerel bir değişken olarak fubar(ve içinde frob) yorumlanacağı anlamına gelir . Buradaki alternatif, çağrılar arasında tutulan, ancak yöntem yerel değişkenlerinin olasılığını kaldıracak, değiştirilmiş bir yerel kapsamla yöntemler yürütmek olacaktır.

Ancak mevcut durum iyi sonuç verir:

 def fubar(self, x)
     self.x = x

 class C:
     frob = fubar

Bir yöntem olarak burada aradığında frobo yoluyla deniyor nesneyi alacak selfparametre ve fubarhala parametre olarak bir nesne ile çağrılabilir ve (aynı işe olduğu aynı C.frobsanırım).


3

İn __init__yöntemi, kendini yeni oluşturulan nesne anlamına gelir; diğer sınıf yöntemlerinde, yöntemi çağrılan örneği ifade eder.

bir isim olarak benlik sadece bir kongre , istediğiniz gibi çağırın! : o kullanırken örnek nesneyi silmek için değil, aynı adı kullanmak zorunda __del__(var), varkullanılan__init__(var,[...])

Daha büyük resmecls sahip olmak için de bir göz atmalısınız . Bu yayın yardımcı olabilir.


3

self, mevcut nesne adı veya sınıf örneği gibi davranıyor.

# Self explanation.


 class classname(object):

    def __init__(self,name):

        self.name=name
        # Self is acting as a replacement of object name.
        #self.name=object1.name

   def display(self):
      print("Name of the person is :",self.name)
      print("object name:",object1.name)


 object1=classname("Bucky")
 object2=classname("ford")

 object1.display()
 object2.display()

###### Output 
Name of the person is : Bucky
object name: Bucky
Name of the person is : ford
object name: Bucky

1

self kaçınılmazdır.

Sadece örtük veya açık olması gereken bir soru vardıself . Guido van RossumBu soru çözüldü diyerek selfkalmalı .

Peki nerede selfyaşıyor?

İşlevsel programlamaya sadık kalırsak ihtiyacımız olmazdı self. Biz girdikten sonra Python OOP bulduğumuzself orada .

İşte class Cyöntem ile tipik kullanım durumum1

class C:
    def m1(self, arg):
        print(self, ' inside')
        pass

ci =C()
print(ci, ' outside')
ci.m1(None)
print(hex(id(ci))) # hex memory address

Bu programın çıktıları:

<__main__.C object at 0x000002B9D79C6CC0>  outside
<__main__.C object at 0x000002B9D79C6CC0>  inside
0x2b9d79c6cc0

Böylece selfsınıf örneğinin bellek adresini tutar. Amacı , örneğin yöntemlerself için referansı tutmak ve bizim için bu referansa açık erişime sahip olmaktır.


Üç farklı sınıf yöntemi türü olduğuna dikkat edin:

  • statik yöntemler (okuma: fonksiyonlar),
  • sınıf yöntemleri,
  • örnek yöntemler (bahsedilen).

0

dan docs ,

yöntemlerle ilgili özel şey, örnek nesnenin işlevin ilk argümanı olarak iletilmesidir. Örneğimizde, çağrı x.f()tam olarak eşdeğerdir MyClass.f(x). Genel olarak, n argüman listesiyle bir yöntemin çağrılması, karşılık gelen işlevin, yöntemin örnek nesnesini ilk argümandan önce ekleyerek oluşturulan bir argüman listesiyle çağrılmasına eşdeğerdir.

bundan önce ilgili pasaj,

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

x = MyClass()


-2

sınıf örneği nesnesine açık bir başvurudır.


21
Bunun richzilla'nın arkasındaki nedeni anlamasına yardımcı olduğunu düşünmüyorum.
Georg Schölly

1
@SilentGhost: çivilenmişsin. Etkilendim. doğru anlıyorsam: Ben tanımlanmış sınıfın bir örneği olarak bir nesne oluşturmak ve self parametre bu nesneyi ifade eder? Benliğin sınıfın kendisine örtük bir şekilde atıfta bulunduğunu anlıyorum, ancak cevabınızı biraz daha açıklarsanız harika olur.
dkrynicki
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.