私は大学の学位のために他の機能を丸める機能を作ろうとしています。たとえば、round_sqrt = round(sqrt)
を呼び出したいのですが、round_sqrt(5)
を呼び出すと、_2
_ではなく_2.23606797749979
_を表示する必要があります。私がしようとしているのはこれです:
_def rounding(funct):
return round(funct)
_
しかし、これは機能しません。
編集:関数にはパラメーターを1つだけ含める必要があります。たとえば、関数の開始は
_def rounding(func):
_
したがって、この関数ではfunct
関数を丸める必要があります。 rounding(abs)(3.2)
を呼び出すと、_3
_と表示されます。
具体的な例として、次のように書くことができます
_def round_sqrt(x):
return round(sqrt(x))
_
アレックスの答え これを一般化します。彼は、creates_round_sqrt
_という関数を定義しています。関数がすでに定義されている場合は、引数としてrounder
に渡すだけです:
_round_sqrt = rounder(sqrt)
_
もちろん、必要ない場合は_round_sqrt
_を定義する必要はありません。 rounder(sqrt)(3.2)
は直接呼び出すことができますが、毎回再定義するよりも、複数回使用する場合は、rounder
の戻り値を安全に保存する方がはるかに効率的です。
それ以外の場合、デコレータの構文は短い(Alexの例を使用)
_def adder(x, y):
return x + y
adder = rounder(adder)
_
私のコメントで述べたように、これは作曲を実装する例です。数学関数は常に単一の引数を取り、単一の引数を返すため、構成は単純です。そのため、2つの関数f
とg
の構成は、常に次のように簡単に定義できます。
_def compose(f, g):
def h(x): # The name doesn't matter
return f(g(x))
return h
_
それから
_round_sqrt = compose(round, sqrt)
_
(実装に関するあらゆる種類の実際的な懸念を無視すると、Pythonは理論的にはUnicode演算子_∘
_を関数に提供することもできます:_round_sqrt = round ∘ sort
_。説明whyこれが起こらないのは、この回答の範囲外です。
ただし、Pythonでは、関数ははるかに複雑です。それらは複数の引数を取ることができ、任意の数の引数と任意のキーワード引数を受け入れることができ、それぞれが技術的に単一の値を返しますが、その値は複数の値またはdict
と考えられるタプルです。結果として、g
の戻り値を関数f
に渡すには、単純なcompose
関数で簡単に対応できる以上の多くの方法があります。 。
クロージャをチェックアウトする必要があります。
def rounder(func):
def inner(*args, **kwargs):
return round(func(*args, **kwargs))
return inner
次に、@
文字を使用して関数を修飾できます。
@rounder
def adder(x, y):
return x + y
print(adder(1.1, 2.2))
出力3
補足:
functools.wraps
を使用して、元の関数に関する情報(docstring、関数名など)を失わないようにすることができます。関数構成は、Pythonでネイティブにサポートされていません。 @ Alexのソリューション に従ってデコレータを使用できます。 @ chepner's solution のように明示的に新しい関数を定義できます。
または、サードパーティのライブラリを使用できます。たとえば、 toolz.compose
:
from toolz import compose
def adder(x, y):
return x + y
round_adder = compose(round, adder)
round_adder(1.1, 2.2) # 3