Saya ingin tahu perbedaan antara __init__
dan __call__
metode.
Sebagai contoh:
class test:
def __init__(self):
self.a = 10
def __call__(self):
b = 20
Yang pertama digunakan untuk menginisialisasi objek yang baru dibuat, dan menerima argumen yang digunakan untuk melakukan itu:
class Foo:
def __init__(self, a, b, c):
# ...
x = Foo(1, 2, 3) # __init__
Operator mengimplementasikan fungsi panggilan kedua.
class Foo:
def __call__(self, a, b, c):
# ...
x = Foo()
x(1, 2, 3) # __call__
__init__
metode ini digunakan ketika kelas dipanggil untuk menginisialisasi instance, sedangkan__call__
metode dipanggil ketika instance dipanggil__call__
?Mendefinisikan
__call__()
metode kustom di kelas-meta memungkinkan instance kelas dipanggil sebagai fungsi, tidak selalu memodifikasi instance itu sendiri.sumber
__call__
tidak hanya memungkinkan instance digunakan sebagai fungsi ... itu mendefinisikan fungsi function yang dieksekusi ketika instance digunakan sebagai fungsi.Dalam Python, fungsi adalah objek kelas satu, ini berarti: referensi fungsi dapat dikirimkan dalam input ke fungsi dan / atau metode lain, dan dieksekusi dari dalamnya.
Instances of Classes (alias Objects), dapat diperlakukan seolah-olah mereka adalah fungsi: meneruskannya ke metode / fungsi lain dan memanggil mereka. Untuk mencapai ini,
__call__
fungsi kelas harus dikhususkan.def __call__(self, [args ...])
Dibutuhkan sebagai input sejumlah argumen. Asumsix
menjadi instance dari KelasX
,x.__call__(1, 2)
analog dengan memanggilx(1,2)
atau instance itu sendiri sebagai suatu fungsi .Dengan Python,
__init__()
didefinisikan dengan benar sebagai Class Constructor (dan juga__del__()
Class Destructor). Oleh karena itu, ada perbedaan bersih antara__init__()
dan__call__()
: yang pertama membangun instance dari Kelas atas, yang kedua membuat instance tersebut dapat dipanggil sebagai fungsi akan tanpa mempengaruhi siklus hidup objek itu sendiri (yaitu__call__
tidak mempengaruhi siklus hidup konstruksi / penghancuran) tetapi itu dapat memodifikasi keadaan internalnya (seperti yang ditunjukkan di bawah).Contoh.
sumber
def __call__
hanya dengandef update
, kita memberi kelasupdate
metode yang melakukan hal yang sama. Sekarang juga dapat memodifikasi keadaan internal, jika dipanggil di bawah ini sebagais.update(7, 8)
. Jadi, apakah itu__call__
hanya sintaksis gula?__call__
membuat instance dari callable kelas. Mengapa itu diperlukan?Secara teknis
__init__
disebut sekali oleh__new__
ketika objek dibuat, sehingga dapat diinisialisasi.Tetapi ada banyak skenario di mana Anda mungkin ingin mendefinisikan kembali objek Anda, katakan Anda selesai dengan objek Anda, dan mungkin menemukan kebutuhan untuk objek baru. Dengan
__call__
Anda dapat mendefinisikan kembali objek yang sama seolah-olah itu baru.Ini hanya satu kasus, mungkin ada banyak lagi.
sumber
sumber
__init__
akan diperlakukan sebagai Konstruktor di mana sebagai__call__
metode dapat dipanggil dengan objek beberapa kali. Keduanya__init__
dan__call__
fungsi memang mengambil argumen default.sumber
__init__
bukan fungsi konstruktor tetapi__new__
.__init__
dipanggil tepat setelah__new__
__new__
menciptakan instance kelas dan menerima kelas sebagai argumen, sedangkan__init__
konstruktor instance itulah sebabnya ia menerimaself
. Cara mudah untuk melihatnya adalah dengan memanggila = Foo(1,2,3)
fungsi yang akan menerima argumen konstruktor__init__
.Saya akan mencoba menjelaskan ini menggunakan contoh, misalkan Anda ingin mencetak sejumlah syarat dari seri fibonacci. Ingat bahwa 2 syarat pertama dari seri fibonacci adalah 1d. Misalnya: 1, 1, 2, 3, 5, 8, 13 ....
Anda ingin daftar yang berisi angka-angka fibonacci diinisialisasi hanya sekali dan setelah itu harus diperbarui. Sekarang kita dapat menggunakan
__call__
fungsionalitas. Bacalah jawaban @mudit verma. Ini seperti Anda ingin objek dapat dipanggil sebagai fungsi tetapi tidak diinisialisasi ulang setiap kali Anda menyebutnya.Misalnya:
Outputnya adalah:
Jika Anda mengamati output
__init__
dipanggil hanya satu kali saat itulah kelas dipakai untuk pertama kalinya, nanti objek dipanggil tanpa menginisialisasi ulang.sumber
Anda juga dapat menggunakan
__call__
metode yang mendukung penerapan dekorator .Contoh ini diambil dari Pola, Resep, dan Idiom Python 3
Keluaran :
sumber
Jadi,
__init__
dipanggil saat Anda membuat turunan dari kelas apa pun dan menginisialisasi variabel turunan juga.Contoh:
Dan
__call__
dipanggil saat Anda memanggil objek seperti fungsi lainnya.Contoh:
sumber
__init__
adalah metode khusus di kelas Python, itu adalah metode konstruktor untuk sebuah kelas. Disebut setiap kali objek kelas dibangun atau kita dapat mengatakan itu menginisialisasi objek baru. Contoh:Jika kita menggunakan A (), itu akan memberikan kesalahan
TypeError: __init__() missing 1 required positional argument: 'a'
karena memerlukan 1 argumena
karena__init__
.........
__call__
ketika diimplementasikan di Kelas membantu kita memanggil instance Kelas sebagai panggilan fungsi.Contoh:
Di sini jika kita menggunakan B (), itu berjalan dengan baik karena tidak memiliki
__init__
fungsi di sini.sumber
__call__
memungkinkan untuk mengembalikan nilai arbitrer, sementara__init__
menjadi konstruktor mengembalikan instance kelas secara implisit. Seperti yang ditunjukkan dengan tepat oleh jawaban lain,__init__
dipanggil sekali saja, sementara dimungkinkan untuk menelepon__call__
berkali-kali, seandainya instance yang diinisialisasi ditugaskan ke variabel perantara.sumber
Jawaban singkat dan manis sudah disediakan di atas. Saya ingin memberikan beberapa implementasi praktis dibandingkan dengan Java.
Catatan : skenario 1 dan skenario 2 tampaknya sama dalam hal hasil keluaran. Namun dalam scenario1, kami kembali membuat instance instance baru lain1 . Dalam scenario2, kita cukup memodifikasi instance1 yang sudah dibuat .
__call__
menguntungkan di sini karena sistem tidak perlu membuat instance baru.Setara di Jawa
sumber
Kita dapat menggunakan metode panggilan untuk menggunakan metode kelas lain sebagai metode statis.
sumber