Pythonの_(アンダースコア)の扱いまとめ
この記事では、Pythonでの_(アンダースコア)の扱いをまとめます。
Pythonでは、アンダースコアが関数やメソッドの前後に付与されていたり、変数として使用されています。慣例的な用法であったり、システム的な制約を付与する場合があるのですが、たまに忘れてしまってあれ何だっけとなる時があるので、備忘用にまとめていきます。
アンダースコアの位置
アンダースコアは色々な位置で使用されています。 アンダースコアが慣例的、システム的に使われている位置は以下の通りです。
アンダースコアの位置 | 例 |
---|---|
アンダースコアのみ | _ |
先頭に1つのアンダースコア | _foo |
末尾に1つのアンダースコア | foo_ |
先頭に2つのアンダースコア | __foo |
先頭と末尾に2つずつのアンダースコア | __foo__ |
途中に1つ以上のアンダースコア | foo_bar_baz , 10_000_000 |
では、順に説明していきます。
アンダースコアのみ
アンダースコアのみは慣例的な用法で、必要のない値(または一時的な変数)の代入先として使用されます。
例えば、以下のようにfor文でインデックスへのアクセスが不要な場合や
for _ in range(47):
print('Hello, world')
必要のない値や返り値の代入先として使われています。
temp_list = [0, 1, 2, 3]
a, b, _, _ = temp_list
print(a)
# 0
print(b)
# 1
print(_)
# 3
# 3次元座標を取得する関数でx軸だけ必要な場合
x, _, _ = get_coordinate(area)
先頭に1つのアンダースコア
先頭に1つのアンダースコアを付与する対象は、以下のパターンがあります。
- クラス内の変数やメソッド:慣例的な意味合い
- 関数:システム的な制約を受ける場合がある
クラス内の変数やメソッドの先頭にアンダースコアを1つ付与
クラス内の変数やメソッドの先頭にアンダースコアを1つ付与する場合は、慣例的な意味として、「クラス内でのみで参照・使用されるもの」を示します。
つまり、クラス外からアクセスされることを意図されていない変数・メソッドということです。と言っても慣例的な意味合いなので、アクセス自体は可能ですので、あくまでも意思表示(注意喚起)というような形です。
class Test:
def __init__(self):
# _fooはクラス外から直接呼ばれることを意図していない
self._foo = 0
# barメソッドはクラス外から直接呼ばれることも意図している
def bar()
self._foo += 1
return self._foo
# _bazメソッドはクラス外から直接呼ばれることを意図していない
def _baz()
self._foo = 0
return self._foo
t = Test()
# 慣例的にアクセスしてほしくはないが、クラス外からアクセス可能
print(t._foo)
# 0
# クラス外からアクセスされることを想定されており、アクセス可能
print(t.bar())
# 1
# 慣例的にアクセスしてほしくはないが、クラス外からアクセス可能
print(t._baz())
# 0
関数の先頭にアンダースコアを一つ付与
関数の先頭にアンダースコアを一つ付与する場合は、システムな制約を受けます。関数が含まれるモジュールからワイルドカードでインポートする場合に、アンダースコアで始まる関数は読み込まれません。
# test_module.py
def foo():
return 0
def _bar():
return 1
from test_module import *
foo() # test_moduleからインポートされる
_bar() # _が先頭にあるためインポートされない
といってもワイルドカードによるインポートは、何をインポートしているか分からなくなる(名前空間が分からなくなる)ため、使用を推奨されていないので、この事例に当たることは少ないかもしれません。
末尾に1つのアンダースコア
利用したい変数名がPythonの予約キーワード(class, del 等)と同じ場合に、末尾に1つのアンダースコアを付与することで、名前が衝突することに避けます。これも慣例的なアンダースコアの使い方です。
def foo(class_):
print(class_)
なお、pythonの予約キーワードは以下で確認できます。
import keyword
print(keyword.kwlist)
# ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
先頭に2つのアンダースコア
先頭に2つのアンダースコアを付与する対象は、クラスの変数やメソッドです。 上記の場合、対象に対してネームマングリング(Name Mangling)が適用されます。