Bunu destekleyen dillerde birden çok değer döndürmenin standart yolu genellikle tupling .
Seçenek: Bir demet kullanma
Bu önemsiz örneği düşünün:
def f(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return (y0, y1, y2)
Ancak, döndürülen değerlerin sayısı arttıkça bu hızla sorunlu hale gelir. Dört veya beş değer döndürmek isterseniz ne olur? Elbette, onları yakalamaya devam edebilirsiniz, ancak hangi değerin nerede olduğunu unutmak kolaylaşır. Bunları almak istediğiniz her yerde açmak oldukça çirkin.
Seçenek: Sözlük kullanma
Bir sonraki mantıklı adım, bir çeşit 'kayıt gösterimi' tanıtmak gibi görünüyor. Python'da bunu yapmanın bariz yolu a dict
.
Aşağıdakileri göz önünde bulundur:
def g(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return {'y0': y0, 'y1': y1 ,'y2': y2}
(Açık olmak gerekirse, y0, y1 ve y2 sadece soyut tanımlayıcılar içindir. Belirtildiği gibi, pratikte anlamlı tanımlayıcılar kullanırsınız.)
Şimdi, iade edilen nesnenin belirli bir üyesini yansıtabileceğimiz bir mekanizmamız var. Örneğin,
result['y0']
Seçenek: Sınıf kullanma
Ancak başka bir seçenek daha var. Bunun yerine özel bir yapıya dönebiliriz. Bunu Python bağlamında çerçeveledim, ancak eminim diğer diller için de geçerlidir. Gerçekten, eğer C'de çalışıyorsanız, bu tek seçeneğiniz olabilir. İşte gidiyor:
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)
Python önceki iki belki sıhhi tesisat açısından çok benzerdir - sonuçta { y0, y1, y2 }
sadece iç girişler olma sonunda __dict__
bir ReturnValue
.
Küçük nesneler için Python tarafından sağlanan bir ek özellik daha vardır __slots__
. Sınıf şu şekilde ifade edilebilir:
class ReturnValue(object):
__slots__ = ["y0", "y1", "y2"]
def __init__(self, y0, y1, y2):
self.y0 = y0
self.y1 = y1
self.y2 = y2
Gönderen Python Reference Manual :
__slots__
Bildirimi, her bir değişken için bir değeri saklamak için, her bir durumda, örneğin değişken ve rezerv yeterli alan bir dizi alır.__dict__
Her örnek için oluşturulmadığı için boşluk kaydedilir .
Seçenek: Veri kullanma (Python 3.7+)
Python 3.7'nin yeni verilerini kullanarak, otomatik olarak eklenen özel yöntemlerle, yazarak ve diğer faydalı araçlarla bir sınıfa dönün:
@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)
Seçenek: Liste kullanma
Göz ardı ettiğim bir diğer öneri ise Kertenkele Bill'den geliyor:
def h(x):
result = [x + 1]
result.append(x * 3)
result.append(y0 ** y3)
return result
Bu benim en sevdiğim yöntem olsa. Sanırım Haskell'e maruz kaldığım için rahatsız oldum, ancak karışık tip listeler fikri her zaman beni rahatsız etti. Bu özel örnekte liste -not- karışık tiptedir, ancak makul olabilir.
Bu şekilde kullanılan bir liste, tuple ile ilgili olarak anlayabildiğim kadarıyla hiçbir şey kazanmaz. Python'daki listeler ve tuples arasındaki tek gerçek fark, listelerin değiştirilebilir olması , tuples olmamasıdır.
Ben şahsen fonksiyonel programlamadan gelen kuralları yerine getirme eğilimindeyim: aynı türden herhangi bir eleman için listeler ve önceden belirlenmiş türlerde sabit sayıda eleman için tuples kullanın.
Soru
Uzun önsözden sonra kaçınılmaz soru geliyor. Hangi yöntem (sizce) en iyisidir?
y3
, aynı işi de yapacak olan yerel bir ad da kullanabilirsiniz .
y3
, ancak y3 global olarak bildirilmedikçe, buNameError: global name 'y3' is not defined
sadece kullanım sağlar3
mı?