Cara kanonik untuk mengembalikan beberapa nilai dalam bahasa yang mendukungnya seringkali tupling .
Opsi: Menggunakan tuple
Pertimbangkan contoh sepele ini:
def f(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return (y0, y1, y2)
Namun, ini dengan cepat menjadi bermasalah karena jumlah nilai yang dikembalikan meningkat. Bagaimana jika Anda ingin mengembalikan empat atau lima nilai? Tentu, Anda bisa terus menggelitiknya, tetapi mudah melupakan nilai mana. Ini juga agak jelek untuk membongkar mereka di mana pun Anda ingin menerimanya.
Opsi: Menggunakan kamus
Langkah logis berikutnya tampaknya adalah memperkenalkan semacam 'catatan notasi'. Dalam Python, cara yang jelas untuk melakukan ini adalah dengan cara a dict
.
Pertimbangkan yang berikut ini:
def g(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return {'y0': y0, 'y1': y1 ,'y2': y2}
(Untuk lebih jelasnya, y0, y1, dan y2 hanya dimaksudkan sebagai pengidentifikasi abstrak. Seperti yang ditunjukkan, dalam praktiknya Anda akan menggunakan pengidentifikasi yang bermakna.)
Sekarang, kami memiliki mekanisme di mana kami dapat memproyeksikan anggota tertentu dari objek yang dikembalikan. Sebagai contoh,
result['y0']
Opsi: Menggunakan kelas
Namun, ada opsi lain. Kami malah bisa mengembalikan struktur khusus. Saya telah membingkai ini dalam konteks Python, tapi saya yakin itu berlaku untuk bahasa lain juga. Memang, jika Anda bekerja di C ini mungkin satu-satunya pilihan Anda. Ini dia:
class ReturnValue:
def __init__(self, y0, y1, y2):
self.y0 = y0
self.y1 = y1
self.y2 = y2
def g(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return ReturnValue(y0, y1, y2)
Dalam Python dua sebelumnya mungkin sangat mirip dalam hal pipa - setelah semua { y0, y1, y2 }
hanya berakhir menjadi entri dalam internal __dict__
dari ReturnValue
.
Ada satu fitur tambahan yang disediakan oleh Python untuk objek kecil, yaitu __slots__
atribut. Kelas dapat dinyatakan sebagai:
class ReturnValue(object):
__slots__ = ["y0", "y1", "y2"]
def __init__(self, y0, y1, y2):
self.y0 = y0
self.y1 = y1
self.y2 = y2
Dari Manual Referensi Python :
The
__slots__
deklarasi mengambil urutan variabel instance dan cadangan cukup ruang di setiap contoh untuk mengadakan nilai untuk setiap variabel. Spasi disimpan karena__dict__
tidak dibuat untuk setiap instance.
Opsi: Menggunakan dataclass (Python 3.7+)
Menggunakan kacamata baru Python 3.7, kembalikan kelas dengan metode khusus yang ditambahkan secara otomatis, pengetikan dan alat lain yang bermanfaat:
@dataclass
class Returnvalue:
y0: int
y1: float
y3: int
def total_cost(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return ReturnValue(y0, y1, y2)
Opsi: Menggunakan daftar
Saran lain yang saya abaikan berasal dari Bill the Lizard:
def h(x):
result = [x + 1]
result.append(x * 3)
result.append(y0 ** y3)
return result
Ini adalah metode yang paling tidak kusukai. Saya kira saya dinodai oleh paparan Haskell, tetapi gagasan daftar tipe campuran selalu terasa tidak nyaman bagi saya. Dalam contoh khusus ini daftarnya adalah -tidak- jenis campuran, tetapi bisa dibayangkan bisa.
Daftar yang digunakan dengan cara ini benar-benar tidak mendapatkan apa pun sehubungan dengan tuple sejauh yang saya tahu. Satu-satunya perbedaan nyata antara daftar dan tupel dalam Python adalah bahwa daftar dapat diubah , sedangkan tupel tidak.
Saya pribadi cenderung membawa konvensi dari pemrograman fungsional: gunakan daftar untuk sejumlah elemen dari jenis yang sama, dan tuple untuk sejumlah elemen tetap dari tipe yang telah ditentukan.
Pertanyaan
Setelah pembukaan panjang, muncul pertanyaan yang tak terhindarkan. Metode mana (menurut Anda) yang terbaik?
y3
, yang akan melakukan pekerjaan yang sama juga.
y3
, tetapi kecuali y3 dinyatakan global, ini akan menghasilkanNameError: global name 'y3' is not defined
mungkin hanya menggunakan3
?