Başka bir işlevi döndüren bir işlevi nasıl yazabilirim?


93

Python'da make_cylinder_volume(r)başka bir işlevi döndüren bir işlev yazmak istiyorum . Döndürülen işlev bir parametre ile çağrılabilir olmalı hve yüksekliği hve yarıçapı olan bir silindirin hacmini döndürmelidir r.

Python'daki işlevlerden nasıl değer döndürüleceğini biliyorum , ancak başka bir işlevi nasıl döndürürüm ?


Yanıtlar:


191

Bunu Python kullanarak deneyin:

import math
def make_cylinder_volume_func(r):
    def volume(h):
        return math.pi * r * r * h
    return volume

Bunu şu şekilde kullanın, örneğin radius=10ve ile height=5:

volume_radius_10 = make_cylinder_volume_func(10)
volume_radius_10(5)
=> 1570.7963267948967

Bir işlevi döndürmenin, işlevin içinde yeni bir işlevi tanımlamanın ve sonunda onu döndürmenin basit bir meselesi olduğuna dikkat edin - her işlev için uygun parametreleri iletirken dikkatli olun. Bilginize, başka bir işlevden bir işlevi döndürme tekniği, curry olarak bilinir .


1
Yani 10geçtiğin bir yerde mi saklanıyor? Çöp ne zaman toplanıyor?
sudo


19

Anonim işlevler olarak da bilinen lambdas'ı kullanarak, volumeiçindeki işlevi make_cylinder_volume_functek bir satıra soyutlayabilirsiniz . Óscar López'in cevabından hiçbir şekilde farklı olarak, lambda kullanan çözüm hala bir bakıma 'daha işlevsel'.

Lambda ifadesi kullanarak kabul edilen yanıtı şu şekilde yazabilirsiniz:

import math
def make_cylinder_volume_fun(r):
    return lambda h: math.pi * r * r * h

Ve sonra başka herhangi bir curried işlevi gibi arayın:

volume_radius_1 = make_cylinder_volume_fun(1)
volume_radius_1(1) 
=> 3.141592653589793

İstenen şeyi yanıtladığınızı fark ediyorum, ancak anladığım kadarıyla, lambda h:kaldırılsaydı işlev aynı şekilde çalışır mıydı?
schoon

2
@schoon Hayır, bu durumda işe yaramaz. Bu aslında 'değişken kapsam belirleme' ve işlev currying fikrini vurgulamak için çok ilginç bir durumdur (temelde değişken kapsam belirlemeye dayanır). Çalışmamasının nedeni (benim örneğimde), returniradenin sonucu döndürmeden önce değerlendirmeye çalışması ve bir grup değişken olduğu için bir miktar float değeri döndürecektir (bir işlevi döndürmeyi deneyin ve işe yarayacaktır). lambdaAşağıdaki kodun değerlendirilmemesi gerektiğini ve ayrıca döndürülen fonksiyonlarda r değişkeninin kapsamının korunacağını söyler make_cylinder...
DaveIdito

10

Bunu pymonad ile yapabileceğinizi belirtmek isterim.

 import pymonad 

 @pymonad.curry
 def add(a, b):
     return a + b

 add5 = add(5)
 add5(4)
 9

1
from functools import partial add5 = partial(add, 5)Aynı şeyi yapıyor
R3ctor

1

Partiye çok geç kaldığımı biliyorum ama bu çözümü ilginç bulabileceğinizi düşünüyorum.

from math import pi
from functools import partial

def cylinder_volume(r, h):
    return pi * r * r * h

make_cylinder_with_radius_2 = partial(cylinder_volume, 2)
make_cylinder_with_height_3 = partial(cylinder_volume, h=3)

print(cylinder_volume(2, 3))            # 37.6991118431
print(make_cylinder_with_radius_2(3))   # 37.6991118431
print(make_cylinder_with_height_3(2))   # 37.6991118431

İşte nasıl çalıştığına dair belgelerpartial .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.