[解決済み] Pythonの関数チェイン
質問
質問 Codewars.com 以下のようなタスクに遭遇しました。
関数を作成する
add
を作り、連続して呼ばれたときに数字を足し算するようにします。そこでadd(1)
は1
,add(1)(2)
を返さなければなりません。1+2
, ...
私はPythonの基本をよく知っていますが、このように連続して呼び出せる関数、つまり、関数
f(x)
として呼び出すことができるような
f(x)(y)(z)...
. ここまでは、この表記をどう解釈していいのかもわからない。
数学者である私としては
f(x)(y)
は関数で、すべての
x
に割り当てる関数です。
g_{x}
を返し、その後に
g_{x}(y)
を返し、同様に
f(x)(y)(z)
.
この解釈が正しければ、Pythonは私にとって非常に興味深く思える関数を動的に作成することを可能にします。この 1 時間、Web を検索しましたが、正しい方向への手がかりを見つけることができませんでした。しかし、このプログラミングの概念がどのように呼ばれるかを私は知らないので、これはあまり驚くことではないのかもしれません。
この概念をどのように呼び、どこでそれについてもっと読むことができますか?
どのように解決するのですか?
これが 機能 と同じように連鎖しているのか、それとも 呼び出し可能 を連鎖させることができますが、関数 は を呼び出すことができるので、害はないと思います。いずれにせよ、私が思いつく方法は2つあります。
サブクラス化
int
を定義し
__call__
:
最初の方法は、カスタム
int
サブクラスで
__call__
を定義するサブクラスで、更新された値でそれ自身の新しいインスタンスを返します。
class CustomInt(int):
def __call__(self, v):
return CustomInt(self + v)
機能
add
を返すように定義できるようになりました。
CustomInt
インスタンスを返すと定義できるようになり、それ自身の更新された値を返す callable として、連続して呼び出すことができるようになりました。
>>> def add(v):
... return CustomInt(v)
>>> add(1)
1
>>> add(1)(2)
3
>>> add(1)(2)(3)(44) # and so on..
50
さらに
int
のサブクラスとして、返される値には
__repr__
と
__str__
の動作は
int
s.
しかし、より複雑な操作のためには、他のダンドリを適切に定義する必要があります。
.
コメントで@Caridorcさんが指摘されているように
add
は単純にこうも書ける。
add = CustomInt
クラスをリネームして
add
ではなく
CustomInt
も同様に動作します。
クロージャを定義し、値を得るために追加の呼び出しを必要とします。
私が思いつく唯一の他の方法は、結果を返すために余分な空の引数の呼び出しを必要とする入れ子関数を含むことです。私は
ではなく
を使って
nonlocal
を使わず、Python間で移植できるようにするために関数オブジェクトに属性を付けることを選択します。
def add(v):
def _inner_adder(val=None):
"""
if val is None we return _inner_adder.v
else we increment and return ourselves
"""
if val is None:
return _inner_adder.v
_inner_adder.v += val
return _inner_adder
_inner_adder.v = v # save value
return _inner_adder
これは継続的に自分自身を返す(
_inner_adder
) を返しますが、もし
val
が指定された場合、それをインクリメントします (
_inner_adder += val
)、そうでない場合はそのままの値を返します。先にも述べたように、これには追加の
()
を呼び出す必要があります。
>>> add(1)(2)()
3
>>> add(1)(2)(3)() # and so on..
6
関連
-
[解決済み] 関数内でグローバル変数を使用する
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] 最小限の驚き」と「変更可能なデフォルトの引数
-
[解決済み] Python 3で「1000000000000000 in range(1000000000000001)」はなぜ速いのですか?
-
[解決済み】JavaScriptの関数にデフォルトのパラメータ値を設定する
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み] Django 1.7で初期マイグレーションからマイグレートバックする方法は?
-
[解決済み] 異なる順序で同じ要素を持つ2つのJSONオブジェクトを等しく比較するには?
-
[解決済み] djangoのQueryDictをPythonのDictに変更するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] PythonでのAWS Lambdaのインポートモジュールエラー
-
[解決済み] SQLAlchemy - テーブルのリストを取得する
-
[解決済み] オブジェクトのリストに特定の属性値を持つオブジェクトが含まれているかどうかをチェックする
-
[解決済み] Cythonのコードを含むPythonパッケージはどのように構成すればよいのでしょうか?
-
[解決済み] 異なる順序で同じ要素を持つ2つのJSONオブジェクトを等しく比較するには?
-
[解決済み] virtualenv の `--no-site-packages` オプションを元に戻す。
-
[解決済み] Pythonで、ウェブサイトが404か200かを確認するためにurllibをどのように使用しますか?
-
[解決済み] Pythonでファイルの読み込みと上書きをする
-
[解決済み] 単純な文字列からtimedeltaオブジェクトを作成する方法
-
[解決済み] Pythonでリストが空かどうかをチェックする方法は?重複