iMind Developers Blog

iMind開発者ブログ

Pythonのlocals()の利用

概要

Pythonの組み込み関数locals()についてのメモ書き。

バージョン情報

  • Python 3.6.5

locals()の挙動

Update and return a dictionary representing the current local symbol table. Free variables are returned by locals() when it is called in function blocks, but not in class blocks.

https://docs.python.org/3/library/functions.html#locals

ということでこれを使うとローカル変数が取れる。

試しに呼んで見る。

x = 0
y = 2
print( locals() )
{
    '__name__': '__main__',
    '__doc__': None,
    '__package__': None,
    '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f84722222b0>,
    '__spec__': None,
    '__annotations__': {},
    '__builtins__': <module 'builtins' (built-in)>,
    '__file__': 'bar.py',
    '__cached__': None,
    'x': 0,
    'y': 2
}

__name__や__file__等のお馴染みの変数と並んでx=0, y=2の値が格納されているのが見える。

類似の関数にglobals()がある。名前の通りlocalsはローカルスコープ、globalsはグローバルなスコープを参照する。

変数が定義されてるか確認

locals()を使って変数が定義されているか確認できる。

'x' in locals()
  #=> True

'z' in locals()
  #=> False

locals()を引数に用いる

引数指定が楽にできるケースもある。

例えばStringのformat関数に名前付きで引数を渡す場合、下記のような書き方になるところだが

'x={x}, y={y}'.format(x=x, y=y)

下記のように渡すことができる。

'x={x}, y={y}'.format(**locals())

実行結果はどちらも同じ。

'x=0, y=2'

あまり行儀がいい書き方には見えないけど、類似の記述はOSSのコードとかでもちょくちょく見かける。

locals()を引数で取る関数の記述

下記のような関数があった場合。

def f(x, y):
    print(x, y)

f(**locals())

これにlocals()を引数で渡すと他にいらないキーワードが付いているので当然エラーになる。

TypeError: f() got an unexpected keyword argument '__name__'

キーワード引数を設定しておけば動く。

def f(x, y, **kwargs):
    print(x, y)

f(**locals())

引数の名前が変わると動かなくなるので使い過ぎると変更に弱いコードが生まれそうな、その代わり名前の整合性が取れたコードになりそうな。

改定履歴

Author: Masato Watanabe, Date: 2019-01-17, 記事投稿