LoginSignup
9
6

More than 3 years have passed since last update.

[Python] locals() の使い所

Last updated at Posted at 2020-08-26

Python向けのテンプレートエンジンJinjaのコードリーディングをしていたところ、locals()という見慣れない関数が使われていて、調べてみたのでメモしておきます。

locals()とは?

リファレンスから抜粋すると、

現在のローカルシンボルテーブルを表す辞書を更新して返します。 関数ブロックで locals() を呼び出したときは自由変数が返されますが、クラスブロックでは返されません。 モジュールレベルでは、 locals() と globals() は同じ辞書であることに注意してください。

と、locals()が実行された時点で定義されているローカル変数が返ってくると解釈しました。

試しにインタプリタを起動して、locals()の挙動を確認してみます。

>>> a = 1
>>> def sample(b="2", c=True):
...     d = 4
...     l = locals()
...     print(l)
...     print(type(l))
... 
>>> sample()
{'b': '2', 'c': True, 'd': 4}
<class 'dict'>

スコープ外であるaは取得されず、sampleメソッド内で定義された変数が取得できたことから、リファレンスを読んだ解釈は齟齬なさそうに思います。

jinjaでのlocals()使用箇所

jinjaにはインスタンスの設定情報を上書きするoverlayメソッドが提供されています。

overlayのメソッドを読んでいたところ、locals()が以下のように使用されていました。

jinja/src/jinja2/environment.py
# https://github.com/pallets/jinja/blob/737a4cd41d09878e7e6c584a2062f5853dc30150/src/jinja2/environment.py#L385-L428
    def overlay(
        self,
        block_start_string=missing,
        # ... 省略 ...
        bytecode_cache=missing,
    ):
        # ... 省略 ...
        args = dict(locals())
        # ... 省略 ...
        for key, value in iteritems(args):
            if value is not missing:
                setattr(rv, key, value)

overlayの引数は多いのだが、locals()を使ってargsにまとめ、呼び出し側が指定した値のみを更新するよう、スマートな処理で実装されています。

上記から、locals()は大量の引数を一つのdictにまとめ、次の処理やjinjaのように呼び出し側から指定された値のみを取り出すような処理に向いていると感じました。

まとめ

以下、自分なりのまとめです。

  • locals()は、locals()実行時点までに定義されたローカル変数をdictで取得できる
  • 大量の引数をdictにまとめて処理したいときに使える

以上になります。
書いた内容や解釈に間違い、他の使い道やバットノウハウ等ありましたら、コメントいただけると助かります。 :pray:

9
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6