概要
javascriptでよく用いられる、分割代入によって好きな引数をオブジェクトから取得する方法をpythonでも実装する。
こんな感じのやつ。
const f = ({ a }) => console.log(a) const d = { a: 1, b: 2 } f(d) // => 1
動機
pythonも一応関数型をサポートしている。
関数型チックに書こうとすると、一つのglobalなstateのようなdictionaryを中心に組み立てると便利な場面があり、この実装をやりたくなった。
書くこと
- pythonの引数における分割代入のやり方
- 分割代入において、好きなkeyのデータだけをdictionaryから取得する方法
書かないこと
- 変数代入時の分割代入(引数への分割代入のときとほぼ同じ)
必要な知識
- pythonの分割代入についての簡単な知識
- pythonのキーワード引数についての知識
javascriptの分割代入における引数渡しとそのメリット
reactというフレームワークを例にjavascriptの分割代入について説明する。
reactはUIのパーツをコンポーネントという関数orクラスに分割し、その中で親となるコンポーネントから子にデータを伝達していくことで、画面遷移などを実現していくフレームワークである。
例えば、親がuserがログインしているかどうかの情報とそれ以外のデータを保持しているとする。
{ login: true, other: "other", ... }
また、子はログインしているかだけを見て、表示を変える(例えば、”ログイン”という文字を表示するか”サインアウト”という文字を表示するか)という状況だとする。
つまり必要なデータはこれだけ。
{ login: true }
その時、親は自分の保持するデータをそのまま子に渡して、子はそこから好きなデータだけを取得するようにすると、親と子の結合度が下がり好ましい。
このように親から子に渡るデータのことをprops
などと呼ぶ。

これを実現するために使用されるテクニックが分割代入である。
pythonでの分割代入の基本
pythonでの分割代入は*
を用いて行う。
配列の分割代入
*
を使う。
def ar_print(*args): print(args) a = [1, 2, 3] ar_print(*a) # => (1, 2, 3)
配列など(厳密にはiteratableなオブジェクト)の前に*
をつけて、上のような関数に渡すとargs
にタプルとなって渡る。
辞書の分割代入
**
を使う。
def dic_print(**kwargs): print(kwargs) d = {a: 1, b: 2} dic_print(**d) # => {a: 1, b: 2}
kwargs
に辞書が渡る。
分割代入を用いた引数の選択
辞書の分割代入とキーワード引数を併用して実現する。
def print_a_value(*, a, **rest): print(a) return rest d = {a: 1, b: 2} rest = print_a_value(**a) # => 1 print(rest) # => {b: 2}
*
後ろの引数はキーワード引数になる。
また、restは可変長引数であるため、余った辞書の要素(ここでいうと{b: 2}
)の受け皿となる。
このように引数を渡される関数側からデータを選択することが可能になる。
まとめ
javascriptは関数型+すべてがオブジェクト(辞書みたいなやつ)なせいでこのテクニックは頻繁に使用する。
pythonのようなオブジェクト指向言語ではあまり辞書ベースのデータ保持オブジェクトを使用しない(というか使用しないほうがいい)なため、このテクニックを使用することはあまりない。
まあ関数型チックな構成にするときは使うとハッピーになることがあるかもしれない。