Apa tujuan dari kata 'diri'?

1130

Apa tujuan dari selfkata dalam Python? Saya mengerti itu merujuk ke objek spesifik yang dibuat dari kelas itu, tapi saya tidak bisa melihat mengapa itu secara eksplisit perlu ditambahkan ke setiap fungsi sebagai parameter. Sebagai ilustrasi, di Ruby saya bisa melakukan ini:

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

Yang saya mengerti, cukup mudah. Namun dalam Python saya harus memasukkan self:

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

Adakah yang bisa membicarakan ini dengan saya? Itu bukan sesuatu yang saya temui dalam pengalaman saya (memang terbatas).

richzilla
sumber
111
Anda mungkin menemukan esai ini menarik "Mengapa diri eksplisit harus tetap" oleh Guido van Rossum: neopythonic.blogspot.com/2008/10/…
unutbu
14
Lihat juga "Mengapa 'diri' harus digunakan secara eksplisit dalam definisi dan panggilan metode": docs.python.org/faq/…
unutbu
37
"Yang saya mengerti, cukup mudah" --- Cukup subjektif, bukan begitu? Apa yang membuat @namelebih intuitif daripada self.name? Yang terakhir, IMO, lebih intuitif.
Santa
14
Itulah perbedaan utama antara fungsi dan metode kelas. Suatu fungsi mengambang bebas, tidak terbebani. Metode kelas (instance) harus mengetahui induknya (dan properti induk) sehingga Anda harus meneruskan metode referensi ke kelas induk (sebagai diri sendiri ). Hanya ada satu aturan yang kurang implisit bahwa Anda harus menginternalisasi sebelum memahami OOP. Bahasa lain memilih gula sintaksis daripada kesederhanaan semantik, python bukan bahasa lain.
Evan Plaice
9
Saya tidak berpikir "eksplisit lebih baik daripada implisit" benar-benar menjelaskan pilihan desain ini dengan baik. @foodan self.foosama-sama eksplisit karena tidak ada resolusi implisit yang perlu terjadi (misalnya dalam C ++, anggota instance dapat "secara implisit" diakses tanpa "secara eksplisit" menggunakan ruang nama). Satu-satunya perbedaan adalah bahwa Ruby memperkenalkan semantik baru (@), sedangkan Python tidak. Apakah atau tidak semantik baru itu sepadan dengan jumlah kata yang dihindari adalah murni subjektif. Meskipun demikian, perlu dicatat bahwa sebagian besar bahasa modern memilih untuk memperkenalkan konsep di sini (misalnya, php's $ this, JS's this).
Jing

Jawaban:

710

Alasan yang perlu Anda gunakan self.adalah karena Python tidak menggunakan @sintaks untuk merujuk ke atribut instance. Python memutuskan untuk melakukan metode dengan cara yang membuat instance yang dimiliki metode dilewatkan secara otomatis, tetapi tidak diterima secara otomatis: parameter pertama metode adalah instance metode dipanggil. Itu membuat metode sepenuhnya sama dengan fungsi, dan meninggalkan nama sebenarnya untuk digunakan terserah Anda (meskipun selfkonvensi, dan orang-orang umumnya akan cemberut pada Anda ketika Anda menggunakan sesuatu yang lain.) selfTidak khusus untuk kode, itu hanya objek lain .

Python dapat melakukan sesuatu yang lain untuk membedakan nama normal dari atribut - sintaks khusus seperti yang dimiliki Ruby, atau membutuhkan deklarasi seperti C ++ dan Java, atau mungkin sesuatu yang lebih berbeda - tetapi ternyata tidak. Semua Python untuk membuat segala sesuatu menjadi eksplisit, membuatnya menjadi jelas apa itu, dan meskipun ia tidak melakukannya sepenuhnya di mana-mana, ia melakukannya sebagai atribut. Itu sebabnya menugaskan ke atribut instance perlu tahu instance apa yang akan ditugaskan, dan itulah mengapa itu perlu self..

Thomas Wouters
sumber
23
@ Georg: clsmengacu pada objek kelas, bukan objek instance
SilentGhost
17
@ SilentGhost: Sebenarnya, nama parameter pertama adalah apa pun yang Anda inginkan. Pada metode kelas, konvensi adalah untuk digunakan clsdan selfdigunakan secara konvensional untuk metode contoh. Jika saya mau, saya bisa menggunakan metode selfdan clsmetode misalnya. Saya juga bisa menggunakan bobdan fnordjika saya suka.
SingleNegationElimination
67
Saya merasa menarik bahwa komunitas tidak memilih thisbukan self. Apakah selfada riwayat yang tidak saya sadari dalam bahasa pemrograman yang lebih lama?
Jules GM
24
@ Julius The selfdatang dari konvensi Modula-3, lihat jawaban ini untuk perincian lebih lanjut tentang pilihan ini. (Penafian: miliknya).
Bakuriu
9
@ Julius Kata selfkunci (Smalltalk, 1980) mendahului thiskata kunci (dari C ++). Lihat: stackoverflow.com/questions/1079983/...
Wes Turner
425

Mari kita ambil kelas vektor sederhana:

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

Kami ingin memiliki metode yang menghitung panjangnya. Seperti apa jadinya jika kita ingin mendefinisikannya di dalam kelas?

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

Seperti apa seharusnya ketika kita mendefinisikannya sebagai metode / fungsi global?

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

Jadi seluruh struktur tetap sama. Bagaimana saya bisa memanfaatkan ini? Jika kita berasumsi bahwa kita belum menulis lengthmetode untuk Vectorkelas kita, kita dapat melakukan ini:

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

Ini berfungsi karena parameter pertama length_global, dapat digunakan kembali sebagai selfparameter dalam length_new. Ini tidak akan mungkin terjadi tanpa eksplisit self.


Cara lain untuk memahami perlunya eksplisit selfadalah untuk melihat di mana Python menambahkan beberapa gula sintaksis. Ketika Anda ingat, itu pada dasarnya, panggilan seperti

v_instance.length()

diubah secara internal menjadi

Vector.length(v_instance)

mudah untuk melihat di mana selfcocok. Anda tidak benar-benar menulis contoh metode dengan Python; apa yang Anda tulis adalah metode kelas yang harus mengambil contoh sebagai parameter pertama. Dan karena itu, Anda harus menempatkan parameter instance di suatu tempat secara eksplisit.

Debilski
sumber
4
Vector.length_new = length_global ... Saya sebenarnya mulai menggunakan sintaksis seperti ini di deklarasi kelas saya. Setiap kali saya hanya ingin mewarisi beberapa metode dari kelas lain, saya hanya secara eksplisit menyalin referensi ke metode tersebut.
Jeeyoung Kim
2
apakah adil untuk mengatakan bahwa "metode instance" python hanyalah gula sintaksis dari metode global statis (seperti di Jawa atau C ++) dengan objek instance yang diteruskan ke paket beberapa atribut? --- yah ini agak setengah benar karena dalam polimorfisme, tujuan yang lebih penting dari "ini" (seperti dalam java) atau "diri" adalah untuk memberi Anda implementasi metode yang benar. Python memang memiliki ini. jadi memanggil myobj.someMethod () sama dengan TheClassOfMyObj.someMethod (myobj) dengan python. perhatikan bahwa "TheClassOfMyObj" secara otomatis ditentukan oleh python dari "self", jika tidak Anda harus mencari tahu.
teddy teddy
3
Infact, tidak hanya metode instan hanya metode kelas, tetapi metode hanya fungsi yang merupakan anggota kelas, seperti yang Vector.length_new = length_globalditunjukkan.
RussW
1
"Ini berfungsi, karena parameter pertama length_global, dapat digunakan kembali sebagai parameter mandiri dalam length_new. Ini tidak akan mungkin terjadi tanpa diri yang eksplisit." - itu akan bekerja sama saja. itu akan digunakan kembali untuk diri implisit ... contoh kedua adalah alasan melingkar - Anda harus secara eksplisit menempatkan diri di sana, karena python membutuhkan diri yang eksplisit.
Karoly Horvath
1
@ KarolyHorvath: Tentu, itu juga akan mungkin untuk memiliki bahasa dengan model di mana metode yang didefinisikan secara internal tidak memerlukan diri yang eksplisit tetapi metode yang ditentukan secara eksternal melakukannya. Tapi saya akan mengatakan ada beberapa konsistensi dalam membutuhkan diri eksplisit dalam kedua kasus, yang membuatnya menjadi alasan yang sah untuk melakukannya dengan cara ini. Bahasa lain dapat memilih pendekatan yang berbeda.
Debilski
422

Katakanlah Anda memiliki kelas ClassAyang berisi metode yang methodAdidefinisikan sebagai:

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

dan ObjectAmerupakan turunan dari kelas ini.

Sekarang ketika ObjectA.methodA(arg1, arg2)dipanggil, python secara internal mengubahnya untuk Anda sebagai:

ClassA.methodA(ObjectA, arg1, arg2)

The selfvariabel mengacu pada objek itu sendiri.

Arjun Sreedharan
sumber
94
Saya membaca semua jawaban lain dan mengerti, saya membaca yang ini dan kemudian semuanya masuk akal.
Seth
3
Ini berhasil bagi saya!
Bernard 'Beta Berlin' Parah
2
Mengapa tidak menyimpan nyali itu di dalam, seperti yang dilakukan Ruby?
Cees Timmerman
Tetapi dalam metode __init __ (self), ia menerima diri, lalu bahkan tanpa membuat objek, bagaimana itu merujuk pada dirinya sendiri?
saurav
Serius, ini jauh lebih baik daripada contoh Debilski karena tidak terlalu rumit dan orang mungkin tidak terbiasa dengan vektor.
NoName
215

Ketika objek dipakai, objek itu sendiri dilewatkan ke dalam parameter diri.

masukkan deskripsi gambar di sini

Karena itu, data objek terikat ke objek. Di bawah ini adalah contoh bagaimana Anda ingin memvisualisasikan apa yang terlihat dari data setiap objek. Perhatikan bagaimana 'diri' diganti dengan nama objek. Saya tidak mengatakan contoh diagram di bawah ini sepenuhnya akurat tetapi mudah-mudahan dengan tujuan untuk memvisualisasikan penggunaan diri.

masukkan deskripsi gambar di sini

Objek diteruskan ke parameter diri sehingga objek dapat menyimpan datanya sendiri.

Meskipun ini mungkin tidak sepenuhnya akurat, pikirkan proses instantiasi objek seperti ini: Ketika sebuah objek dibuat, ia menggunakan kelas sebagai templat untuk data dan metode sendiri. Tanpa meneruskan namanya sendiri ke parameter diri, atribut dan metode di kelas akan tetap sebagai templat umum dan tidak akan dirujuk ke (milik) objek. Jadi dengan memasukkan nama objek ke dalam parameter diri itu berarti bahwa jika 100 objek dibuat dari satu kelas, mereka semua dapat melacak data dan metode mereka sendiri.

Lihat ilustrasi di bawah ini:

masukkan deskripsi gambar di sini

sw123456
sumber
Hai, ketika mengakses atribut Bob misalnya dengan "bob.name ()", Anda sebenarnya mengakses bob (). Self.name jadi untuk berbicara dari ' init ' kan?
udarH3
3
Ketika Anda menulis bob.name () di komentar di atas, Anda menyiratkan bahwa bob memiliki metode yang disebut nama () karena Anda menambahkan tanda kurung setelah nama. Namun dalam contoh ini tidak ada metode seperti itu. 'bob.name' (yang tidak memiliki tanda kurung) secara langsung mengakses atribut yang disebut nama dari metode init (konstruktor). Ketika metode bicara bob dipanggil, itu adalah metode yang mengakses atribut nama dan mengembalikannya dalam pernyataan cetak. Semoga ini membantu.
sw123456
3
Tidak, Anda mendapatkan nilai self.name, yang untuk objek bob sebenarnya bob.name, karena nama objek diteruskan ke parameter diri ketika dibuat (dipakai). Sekali lagi, semoga ini membantu. Jangan ragu untuk mengunggah posting utama jika ada.
sw123456
2
Nama diberikan ke self.name di instantiation. Setelah objek dibuat, semua variabel yang termasuk dalam objek adalah yang diawali dengan 'diri'. Ingatlah bahwa diri diganti dengan nama objek saat dibuat dari kelas.
sw123456
5
Ini adalah bagaimana Anda menjelaskan banyak hal! kerja bagus :)
penta
80

Saya suka contoh ini:

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: []
kame
sumber
18
jadi vars tanpa diri hanyalah vars statis kelas, seperti di java
teddy teddy
5
teddy teddy, kamu tidak sepenuhnya benar. Perilaku (seperti statis atau non-statis) tidak hanya bergantung pada selftetapi juga pada tipe variabel. Coba lakukan contoh pertama dengan integer sederhana, bukan daftar. Hasilnya akan sangat berbeda.
Konstantin
2
Sebenarnya, pertanyaan saya dengan ini adalah mengapa Anda diizinkan untuk mengatakan a.foodalam contoh pertama, bukan A.foo? Jelas foomilik kelas ...
Radon Rosborough
Anda dapat memanggil anggota statis dari instance objek dalam sebagian besar bahasa. Mengapa itu mengejutkan?
Paarth
2
@RadonRosborough Karena dalam contoh pertama, adan bkeduanya label (atau pointer) untuk A()(kelas). a.fooreferensi A().foometode kelas. Dalam contoh kedua, meskipun, amenjadi referensi ke sebuah instance dari A(), seperti halnya b. Sekarang mereka adalah instance daripada objek kelas itu sendiri, self memungkinkan foometode untuk beroperasi pada instance.
LegendaryDude
40

Saya akan menunjukkan dengan kode yang tidak menggunakan kelas :

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'

Kelas hanyalah cara untuk menghindari lulus dalam "keadaan" hal ini sepanjang waktu (dan hal-hal baik lainnya seperti inisialisasi, komposisi kelas, metaclasses yang jarang dibutuhkan, dan mendukung metode kustom untuk menimpa operator).

Sekarang mari kita tunjukkan kode di atas menggunakan mesin kelas python bawaan, untuk menunjukkan bagaimana pada dasarnya hal yang sama.

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 )

[memigrasikan jawaban saya dari pertanyaan tertutup rangkap]

ninjagecko
sumber
1
Saya berharap Python menutup-nutupi para penangannya seperti halnya Ruby.
Cees Timmerman
20

Kutipan berikut berasal dari dokumentasi Python tentang diri :

Seperti dalam Modula-3, tidak ada singkatan [dengan Python] untuk mereferensikan anggota objek dari metodenya: fungsi metode dideklarasikan dengan argumen pertama eksplisit yang mewakili objek, yang disediakan secara implisit oleh panggilan.

Seringkali, argumen pertama dari suatu metode disebut diri. Ini tidak lebih dari sebuah konvensi: nama diri sama sekali tidak memiliki arti khusus untuk Python. Perhatikan, bagaimanapun, bahwa dengan tidak mengikuti konvensi kode Anda mungkin kurang dapat dibaca oleh programmer Python lain, dan juga dapat dibayangkan bahwa program browser kelas dapat ditulis yang bergantung pada konvensi semacam itu.

Untuk informasi lebih lanjut, lihat tutorial dokumentasi Python di kelas .

Matthew Rankin
sumber
20

Seperti halnya semua alasan lain yang telah dinyatakan, ini memungkinkan akses yang lebih mudah ke metode yang diganti; kamu bisa menelepon Class.some_method(inst).

Contoh di mana itu berguna:

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"
Ponkadoodle
sumber
17

Penggunaannya mirip dengan penggunaan thiskata kunci di Jawa, yaitu untuk memberikan referensi ke objek saat ini.

Gaurav Nishant
sumber
2
class myClass: def myFunc (this, name): this.name = name
LEMUEL ADANE
16

Python bukan bahasa yang dibangun untuk Pemrograman Berorientasi Objek tidak seperti Java atau C ++.

Saat memanggil metode statis dengan Python, seseorang cukup menulis metode dengan argumen reguler di dalamnya.

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

Namun, metode objek, yang mengharuskan Anda membuat variabel, yang merupakan Hewan, dalam hal ini, membutuhkan argumen sendiri

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

Metode mandiri juga digunakan untuk merujuk ke bidang variabel dalam kelas.

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


    def getAnimalName(self):
        return self.animalName

Dalam hal ini, self merujuk ke variabel animalName dari seluruh kelas. INGAT: Jika Anda memiliki variabel dalam suatu metode, self tidak akan berfungsi. Variabel itu hanya ada hanya saat metode itu berjalan. Untuk mendefinisikan bidang (variabel dari seluruh kelas), Anda harus mendefinisikannya di luar metode kelas.

Jika Anda tidak mengerti satu kata pun dari apa yang saya katakan, maka Google "Pemrograman Berorientasi Objek." Setelah Anda memahami ini, Anda bahkan tidak perlu mengajukan pertanyaan itu :).

ytpillai
sumber
+1 karena perbedaan antara staticMethod()dan objectMethod(self). Saya ingin menambahkan bahwa untuk memohon yang pertama, Anda akan mengatakan Animal.staticMethod(), sementara objectMethod()membutuhkan sebuah contoh:a = Animal(); a.objectMethod()
Laryx Decidua
Apa yang Anda katakan tidak 100% benar. Itu hanya sebuah konvensi. Anda masih dapat memanggil metode statis dari objek yang dibuat. Anda tidak akan dapat menggunakan anggota kelas apa pun karena Anda tidak mendeklarasikan diri. Saya bahkan dapat memanggil Animal.objectMethod (animalObj) untuk memanggil yang tidak statis. Pada dasarnya ini berarti metode statis hanya metode yang tidak menggunakan variabel anggota. Seharusnya tidak perlu menyatakan diri. Menurut saya itu persyaratan bahasa yang konyol. Bahasa seperti Lua dan C ++ memberi Anda variabel obj di belakang layar.
user441521
Anda membuat pernyataan string animalName yang tidak berguna dan menabrak metode animalName.
Cees Timmerman
3
@ytpillai Tidak Relevan. Kode yang membingungkan dan salah seharusnya tidak disajikan sebagai jawaban.
Cees Timmerman
1
def getAnimalNameuntuk tidak memecahkan string yang ingin Anda kembalikan, dan selfmerujuk ke instance kelas, bukan bidang apa pun di dalamnya.
Cees Timmerman
10

Itu ada di sana untuk mengikuti Python zen "eksplisit lebih baik daripada implisit". Itu memang referensi ke objek kelas Anda. Dalam Java dan PHP, misalnya, ini disebut this.

Jika user_type_nameadalah bidang pada model Anda, Anda mengaksesnya self.user_type_name.

dan-klasson
sumber
10

Pertama-tama, diri adalah nama konvensional, Anda dapat menempatkan hal lain (koheren) sebagai gantinya.

Itu merujuk ke objek itu sendiri, jadi ketika Anda menggunakannya, Anda menyatakan bahwa .name dan .age adalah properti dari objek Student (catatan, bukan dari kelas Student) yang akan Anda buat.

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

Kode ada di sini

Akash Kandpal
sumber
1
Jawaban Anda tampaknya paling jelas bagi saya. +1
Pawel
9

selfadalah referensi objek ke objek itu sendiri, oleh karena itu, mereka sama. Metode python tidak dipanggil dalam konteks objek itu sendiri. selfdi Python dapat digunakan untuk menangani model objek kustom atau sesuatu.

Ming-Tang
sumber
8

Penggunaan argumen, yang biasa disebut selftidak sulit untuk dipahami, seperti mengapa perlu? Atau mengapa menyebutkannya secara eksplisit? Itu, saya kira, adalah pertanyaan yang lebih besar bagi sebagian besar pengguna yang mencari pertanyaan ini, atau jika tidak, mereka pasti akan memiliki pertanyaan yang sama ketika mereka terus belajar python. Saya merekomendasikan mereka untuk membaca beberapa blog ini:

1: Penggunaan diri dijelaskan

Perhatikan bahwa ini bukan kata kunci.

Argumen pertama dari setiap metode kelas, termasuk init, selalu merupakan referensi ke instance kelas saat ini. Dengan konvensi, argumen ini selalu bernama diri. Dalam metode init, self merujuk ke objek yang baru dibuat; dalam metode kelas lain, ini merujuk pada instance yang metodenya dipanggil. Misalnya kode di bawah ini sama dengan kode di atas.

2: Mengapa kita melakukannya dengan cara ini dan mengapa kita tidak bisa menghilangkannya sebagai argumen, seperti Java, dan memiliki kata kunci sebagai gantinya

Hal lain yang ingin saya tambahkan adalah, selfargumen opsional memungkinkan saya untuk mendeklarasikan metode statis di dalam kelas, dengan tidak menulis self.

Contoh kode:

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"

PS : Ini hanya berfungsi di Python 3.x.

Dalam versi sebelumnya, Anda harus menambahkan @staticmethoddekorator secara eksplisit , jika tidak selfargumen wajib.

Bugs Buggy
sumber
7

Saya terkejut tidak ada yang membesarkan Lua. Lua juga menggunakan variabel 'mandiri' namun bisa dihilangkan tetapi masih digunakan. C ++ melakukan hal yang sama dengan 'ini'. Saya tidak melihat alasan untuk harus mendeklarasikan 'diri' di setiap fungsi tetapi Anda masih dapat menggunakannya seperti yang Anda bisa dengan lua dan C ++. Untuk bahasa yang membanggakan diri karena singkat, aneh bahwa itu mengharuskan Anda untuk mendeklarasikan variabel diri.

pengguna441521
sumber
6

Lihatlah contoh berikut, yang dengan jelas menjelaskan tujuan 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 digunakan / dibutuhkan untuk membedakan antara instance.

Sumber: variabel diri dalam python menjelaskan - Pythontips

kmario23
sumber
Ya, saya pikir kita tahu mengapa diri digunakan, tetapi pertanyaannya adalah mengapa bahasa membuat Anda secara eksplisit menyatakannya. Banyak bahasa lain tidak memerlukan ini dan bahasa yang membanggakan diri karena singkat, Anda akan berpikir mereka hanya akan memberi Anda variabel di belakang layar untuk digunakan seperti Lua atau C ++ (ini).
user441521
3
@ kmario23 Respons Anda berasal dari sini: pythontips.com/2013/08/07/the-self-variable-in-python-explained Harap selalu mengakui penulis asli saat memposting jawaban sebagai milik Anda.
geekidharsh
@geekidharsh terima kasih, saya menambahkan catatan!
kmario23
5

Apakah karena cara python dirancang alternatif tidak akan bekerja. Python dirancang untuk memungkinkan metode atau fungsi didefinisikan dalam konteks di mana keduanya implisit this(a-la Java / C ++) atau eksplisit @(a-la ruby) tidak akan berfungsi. Mari kita ambil contoh dengan pendekatan eksplisit dengan konvensi python:

def fubar(x):
    self.x = x

class C:
    frob = fubar

Sekarang fubarfungsi tidak akan berfungsi karena akan menganggap itu selfadalah variabel global (dan frobjuga). Alternatifnya adalah dengan mengeksekusi metode dengan ruang lingkup global yang diganti (di mana selfobjek).

Pendekatan implisit akan menjadi

def fubar(x)
    myX = x

class C:
    frob = fubar

Ini berarti bahwa myXakan ditafsirkan sebagai variabel lokal dalam fubar(dan frobjuga). Alternatif di sini adalah untuk mengeksekusi metode dengan ruang lingkup lokal diganti yang dipertahankan antara panggilan, tetapi itu akan menghapus kemungkinan variabel metode lokal.

Namun situasi saat ini berjalan dengan baik:

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

 class C:
     frob = fubar

di sini ketika disebut sebagai metode frobakan menerima objek yang itu disebut melalui selfparameter, dan fubarmasih bisa disebut dengan objek sebagai parameter dan bekerja sama (itu adalah sama dengan C.frobsaya pikir).

meroket
sumber
3

Dalam __init__metode ini, self merujuk ke objek yang baru dibuat; dalam metode kelas lain, ini merujuk pada instance yang metodenya dipanggil.

diri, sebagai sebuah nama, hanyalah sebuah konvensi , sebut saja yang Anda inginkan! tetapi ketika menggunakannya, misalnya untuk menghapus objek, Anda harus menggunakan nama yang sama:, di __del__(var)mana vardigunakan dalam__init__(var,[...])

Anda harus melihat clsjuga, untuk memiliki gambaran yang lebih besar . Posting ini bisa membantu.

Oussama L.
sumber
3

self bertindak seperti nama objek saat ini atau instance dari kelas.

# 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
sameer_nubia
sumber
1

self tidak bisa dihindari.

Hanya ada pertanyaan yang harusnya selfimplisit atau eksplisit. Guido van Rossumterselesaikan pertanyaan ini mengatakan pepatah selfharus tetap .

Jadi dimana tempat selftinggalnya?

Jika kita hanya berpegang pada pemrograman fungsional kita tidak perlu self. Setelah kami memasukkan Python OOP, kami menemukanself sana.

Berikut ini adalah kasus penggunaan umum class Cdengan metode inim1

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

Program ini akan menampilkan:

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

Jadi selfpegang alamat memori instance kelas. Tujuan dari selfakan memegang referensi untuk metode instan dan bagi kita untuk memiliki eksplisit akses ke referensi itu.


Perhatikan ada tiga jenis metode kelas:

  • metode statis (baca: fungsi),
  • metode kelas,
  • metode instance (disebutkan).
prosti
sumber
0

dari dokumen ,

hal khusus tentang metode adalah objek instance dilewatkan sebagai argumen pertama dari fungsi. Dalam contoh kami, panggilan x.f()persis sama dengan MyClass.f(x). Secara umum, memanggil metode dengan daftar argumen n sama dengan memanggil fungsi yang sesuai dengan daftar argumen yang dibuat dengan memasukkan objek instance metode sebelum argumen pertama.

sebelum ini cuplikan terkait,

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

    def f(self):
        return 'hello world'

x = MyClass()

nmxl
sumber
-2

ini adalah referensi eksplisit ke objek instance kelas.

SilentGhost
sumber
21
Saya tidak berpikir ini membantu richzilla untuk memahami alasan di baliknya.
Georg Schölly
1
@ SilentGhost: Anda telah memakukannya. Saya terkesan. jika saya memahaminya dengan benar: Saya membuat objek sebagai turunan dari kelas yang didefinisikan dan parameter self merujuk ke objek itu? Saya mengerti diri merujuk secara implisit ke kelas itu sendiri tetapi akan lebih baik jika Anda menjelaskan jawaban Anda sedikit lebih.
dkrynicki