Meneruskan diri ke metode kelas python

Parameter self_ adalah referensi ke instance kelas saat ini, dan digunakan untuk mengakses variabel milik kelas

Itu tidak harus diberi nama self , Anda dapat menyebutnya apa pun yang Anda suka, tetapi itu harus menjadi parameter pertama dari fungsi apa pun di kelas

Jika Anda telah memprogram dengan Python (pemrograman berorientasi objek) selama beberapa waktu, maka Anda pasti menemukan metode yang memiliki

cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
3 sebagai parameter pertama mereka

Mari kita coba memahami apa parameter diri yang berulang ini


Apa itu diri dalam Python?

Dalam pemrograman berorientasi objek, setiap kali kita mendefinisikan metode untuk kelas, kita menggunakan

cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
3 sebagai parameter pertama dalam setiap kasus. Mari kita lihat definisi kelas yang disebut
cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
5

class Cat:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def info(self):
        print(f"I am a cat. My name is {self.name}. I am {self.age} years old.")

    def make_sound(self):
        print("Meow")

Dalam hal ini semua metode, termasuk

cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
_6, memiliki parameter pertama sebagai
cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
3

Kita tahu bahwa kelas adalah cetak biru untuk objek. Cetak biru ini dapat digunakan untuk membuat banyak objek. Mari buat dua objek berbeda dari kelas di atas

cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)

Kata kunci

cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
3 digunakan untuk mewakili instance (objek) dari kelas yang diberikan. Dalam hal ini, dua objek
cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
5
class Point(object):
    def __init__(self,x = 0,y = 0):
        self.x = x
        self.y = y

    def distance(self):
        """Find distance from origin"""
        return (self.x**2 + self.y**2) ** 0.5
0 dan
class Point(object):
    def __init__(self,x = 0,y = 0):
        self.x = x
        self.y = y

    def distance(self):
        """Find distance from origin"""
        return (self.x**2 + self.y**2) ** 0.5
1 memiliki atribut
class Point(object):
    def __init__(self,x = 0,y = 0):
        self.x = x
        self.y = y

    def distance(self):
        """Find distance from origin"""
        return (self.x**2 + self.y**2) ** 0.5
2 dan
class Point(object):
    def __init__(self,x = 0,y = 0):
        self.x = x
        self.y = y

    def distance(self):
        """Find distance from origin"""
        return (self.x**2 + self.y**2) ** 0.5
3 sendiri. Jika tidak ada argumen mandiri, kelas yang sama tidak dapat menyimpan informasi untuk kedua objek ini

Namun, karena kelas hanyalah cetak biru,

cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
3 mengizinkan akses ke atribut dan metode setiap objek dengan python. Ini memungkinkan setiap objek memiliki atribut dan metodenya sendiri. Jadi, bahkan jauh sebelum membuat objek ini, kita mereferensikan objek sebagai
cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
3 saat mendefinisikan kelas


Mengapa diri didefinisikan secara eksplisit setiap saat?

Bahkan ketika kita memahami penggunaan

cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
3, mungkin masih tampak aneh, terutama bagi pemrogram yang berasal dari bahasa lain, bahwa
cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
3 diteruskan sebagai parameter secara eksplisit setiap kali kita mendefinisikan metode. Seperti yang dikatakan The Zen of Python, "Eksplisit lebih baik daripada implisit"

Jadi, mengapa kita perlu melakukan ini? . Kami memiliki kelas

class Point(object):
    def __init__(self,x = 0,y = 0):
        self.x = x
        self.y = y

    def distance(self):
        """Find distance from origin"""
        return (self.x**2 + self.y**2) ** 0.5
_8 yang mendefinisikan metode
class Point(object):
    def __init__(self,x = 0,y = 0):
        self.x = x
        self.y = y

    def distance(self):
        """Find distance from origin"""
        return (self.x**2 + self.y**2) ** 0.5
9 untuk menghitung jarak dari titik asal

class Point(object):
    def __init__(self,x = 0,y = 0):
        self.x = x
        self.y = y

    def distance(self):
        """Find distance from origin"""
        return (self.x**2 + self.y**2) ** 0.5
_

Sekarang mari kita buat instance kelas ini dan temukan jaraknya

>>> p1 = Point(6,8)
>>> p1.distance()
10.0

Dalam contoh di atas,

>>> p1 = Point(6,8)
>>> p1.distance()
10.0
_0 mendefinisikan tiga parameter tetapi kami hanya melewati dua (6 dan 8). Demikian pula
>>> p1 = Point(6,8)
>>> p1.distance()
10.0
1 membutuhkan satu tetapi tidak ada argumen yang diberikan. Mengapa Python tidak mengeluh tentang ketidakcocokan nomor argumen ini?


Apa yang Terjadi Secara Internal?

>>> p1 = Point(6,8)
>>> p1.distance()
10.0
2 dan
>>> p1 = Point(6,8)
>>> p1.distance()
10.0
3 pada contoh di atas berbeda dan tidak persis sama

>>> type(Point.distance)
<class 'function'>
>>> type(p1.distance)
<class 'method'>

Kita dapat melihat bahwa yang pertama adalah sebuah fungsi dan yang kedua adalah sebuah metode. Suatu hal yang aneh tentang metode (dalam Python) adalah objek itu sendiri diteruskan sebagai argumen pertama ke fungsi yang sesuai

Dalam kasus contoh di atas, pemanggilan metode

>>> p1 = Point(6,8)
>>> p1.distance()
10.0
4 sebenarnya setara dengan
>>> p1 = Point(6,8)
>>> p1.distance()
10.0
5

Umumnya, ketika kita memanggil sebuah metode dengan beberapa argumen, fungsi kelas terkait dipanggil dengan menempatkan objek metode sebelum argumen pertama. Jadi, sesuatu seperti

>>> p1 = Point(6,8)
>>> p1.distance()
10.0
_6 menjadi
>>> p1 = Point(6,8)
>>> p1.distance()
10.0
7. Proses pemanggilan otomatis sedangkan proses penerimaan tidak (eksplisit)

Ini adalah alasan mengapa parameter pertama dari sebuah fungsi di kelas haruslah objek itu sendiri. Menulis parameter ini sebagai

cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
_3 hanyalah sebuah konvensi. Ini bukan kata kunci dan tidak memiliki arti khusus di Python. Kita bisa menggunakan nama lain (seperti
>>> p1 = Point(6,8)
>>> p1.distance()
10.0
9) tetapi sangat tidak dianjurkan. Menggunakan nama selain
cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
_3 tidak disukai oleh sebagian besar pengembang dan menurunkan keterbacaan kode (Jumlah keterbacaan)


Diri Bisa Dihindari

Sekarang Anda sudah jelas bahwa objek (instance) itu sendiri diteruskan sebagai argumen pertama, secara otomatis. Perilaku implisit ini dapat dihindari saat membuat metode statis. Perhatikan contoh sederhana berikut

class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")

Di sini,

>>> type(Point.distance)
<class 'function'>
>>> type(p1.distance)
<class 'method'>
1 adalah dekorator fungsi yang membuat
>>> type(Point.distance)
<class 'function'>
>>> type(p1.distance)
<class 'method'>
2 statis. Mari kita buat instance kelas ini dan panggil metodenya

>>> a = A()
>>> a.stat_meth()
Look no self was passed

Dari contoh di atas, kita dapat melihat bahwa perilaku implisit meneruskan objek sebagai argumen pertama dihindari saat menggunakan metode statis. Secara keseluruhan, metode statis berperilaku seperti fungsi lama biasa (Karena semua objek kelas berbagi metode statis)

>>> type(A.stat_meth)
<class 'function'>
>>> type(a.stat_meth)
<class 'function'>

Diri Ada Di Sini Untuk Tetap

cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
3 eksplisit tidak unik untuk Python. Ide ini dipinjam dari Modula-3. Berikut ini adalah kasus penggunaan yang berguna

Tidak ada deklarasi variabel eksplisit di Python. Mereka beraksi pada tugas pertama. Penggunaan

cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
_3 membuatnya lebih mudah untuk membedakan antara atribut instance (dan metode) dari variabel lokal

Pada contoh pertama, diri. x adalah atribut instance sedangkan x adalah variabel lokal. Mereka tidak sama dan terletak di ruang nama yang berbeda

Banyak yang telah mengusulkan untuk menjadikan diri sebagai kata kunci dalam Python, seperti

>>> type(Point.distance)
<class 'function'>
>>> type(p1.distance)
<class 'method'>
5 dalam C++ dan Java. Ini akan menghilangkan penggunaan berlebihan
cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
3 eksplisit dari daftar parameter formal dalam metode

Meskipun ide ini tampak menjanjikan, itu tidak akan terjadi. Setidaknya tidak dalam waktu dekat. Alasan utamanya adalah kompatibilitas ke belakang. Ini adalah blog dari pencipta Python sendiri yang menjelaskan mengapa diri yang eksplisit harus tetap ada


__init__() bukan konstruktor

Satu kesimpulan penting yang dapat ditarik dari informasi sejauh ini adalah bahwa metode

>>> p1 = Point(6,8)
>>> p1.distance()
10.0
0 bukanlah sebuah konstruktor. Banyak programmer Python yang naif menjadi bingung karena
>>> p1 = Point(6,8)
>>> p1.distance()
10.0
0 dipanggil saat kita membuat objek

Pemeriksaan lebih dekat akan mengungkapkan bahwa parameter pertama di

>>> p1 = Point(6,8)
>>> p1.distance()
10.0
0 adalah objek itu sendiri (objek sudah ada). Fungsi
>>> p1 = Point(6,8)
>>> p1.distance()
10.0
_0 dipanggil segera setelah objek dibuat dan digunakan untuk menginisialisasinya

Secara teknis, konstruktor adalah metode yang membuat objek itu sendiri. Dalam Python, metode ini adalah

class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")
1. Tanda tangan umum dari metode ini adalah

__new__(cls, *args, **kwargs)

Ketika

class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")
_1 dipanggil, kelas itu sendiri dilewatkan sebagai argumen pertama secara otomatis(
class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")
3)

Sekali lagi, seperti diri sendiri, cls hanyalah konvensi penamaan. Selain itu, *args dan **kwargs digunakan untuk mengambil sejumlah argumen selama pemanggilan metode dengan Python

Beberapa hal penting yang perlu diingat saat menerapkan

class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")
1 adalah

  • class A(object):
    
        @staticmethod
        def stat_meth():
            print("Look no self was passed")
    _1 selalu dipanggil sebelum
    >>> p1 = Point(6,8)
    >>> p1.distance()
    10.0
    0
  • Argumen pertama adalah kelas itu sendiri yang diteruskan secara implisit
  • Selalu kembalikan objek yang valid dari
    class A(object):
    
        @staticmethod
        def stat_meth():
            print("Look no self was passed")
    1. Tidak wajib, tetapi kegunaan utamanya adalah untuk membuat dan mengembalikan objek

Mari kita lihat sebuah contoh

class Point(object):

    def __new__(cls,*args,**kwargs):
        print("From new")
        print(cls)
        print(args)
        print(kwargs)

        # create our object and return it
        obj = super().__new__(cls)
        return obj

    def __init__(self,x = 0,y = 0):
        print("From init")
        self.x = x
        self.y = y

Sekarang, mari kita instantiate itu

cat1 = Cat('Andy', 2)
cat2 = Cat('Phoebe', 3)
0

Contoh ini menggambarkan bahwa

class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")
_1 dipanggil sebelum
>>> p1 = Point(6,8)
>>> p1.distance()
10.0
0. Kita juga dapat melihat bahwa parameter cls di
class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")
1 adalah kelas itu sendiri (
class Point(object):
    def __init__(self,x = 0,y = 0):
        self.x = x
        self.y = y

    def distance(self):
        """Find distance from origin"""
        return (self.x**2 + self.y**2) ** 0.5
8). Terakhir, objek dibuat dengan memanggil metode
class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")
1 pada kelas dasar objek

Dalam Python,

>>> a = A()
>>> a.stat_meth()
Look no self was passed
3 adalah kelas dasar dari mana semua kelas lainnya diturunkan. Dalam contoh di atas, kami melakukannya dengan menggunakan super()


Gunakan __new__ atau __init__?

Anda mungkin sering melihat

>>> p1 = Point(6,8)
>>> p1.distance()
10.0
0 tetapi penggunaan
class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")
1 jarang terjadi. Ini karena sebagian besar waktu Anda tidak perlu menimpanya. Umumnya,
>>> p1 = Point(6,8)
>>> p1.distance()
10.0
_0 digunakan untuk menginisialisasi objek yang baru dibuat sementara
class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")
1 digunakan untuk mengontrol cara objek dibuat

Kita juga dapat menggunakan

class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")
_1 untuk menginisialisasi atribut suatu objek, tetapi secara logis itu harus ada di dalam
>>> p1 = Point(6,8)
>>> p1.distance()
10.0
0

Salah satu penggunaan praktis dari

class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")
1, bagaimanapun, bisa untuk membatasi jumlah objek yang dibuat dari kelas

Misalkan kita menginginkan kelas

>>> type(A.stat_meth)
<class 'function'>
>>> type(a.stat_meth)
<class 'function'>
1 untuk membuat instance untuk mewakili empat simpul persegi. Kami dapat mewarisi dari kelas kami sebelumnya
class Point(object):
    def __init__(self,x = 0,y = 0):
        self.x = x
        self.y = y

    def distance(self):
        """Find distance from origin"""
        return (self.x**2 + self.y**2) ** 0.5
8 (contoh kedua dalam artikel ini) dan menggunakan
class A(object):

    @staticmethod
    def stat_meth():
        print("Look no self was passed")
1 untuk menerapkan pembatasan ini. Berikut adalah contoh untuk membatasi kelas agar hanya memiliki empat instance

Bisakah saya menggunakan metode self in class Python?

Dengan menggunakan "self" kita dapat mengakses atribut dan metode kelas di python . Itu mengikat atribut dengan argumen yang diberikan.

Bisakah Anda memanggil metode kelas sendiri?

Metode instance membutuhkan instance kelas dan dapat mengakses instance melalui self . Metode kelas tidak memerlukan instance kelas. Mereka tidak dapat mengakses instance ( self ) tetapi mereka memiliki akses ke class itu sendiri melalui cls. Metode statis tidak memiliki akses ke cls atau self.

Apakah saya perlu menganggap diri sebagai argumen Python?

Python tidak memaksa Anda untuk menggunakan "self" . Anda dapat memberikannya nama apa pun yang Anda inginkan. Anda hanya perlu mengingat bahwa argumen pertama dalam header definisi metode adalah referensi ke objek.

Apa artinya melewati diri sendiri dengan Python?

Parameter self adalah referensi ke instance kelas saat ini, dan digunakan untuk mengakses variabel milik kelas .