はじめに
Pythonを書いていると、変数名やメソッド名、数値などで_(アンダースコア)を頻繁に見かけると思います。
ただ、_は1つの意味だけではありません。
未使用変数、内部利用の慣習、名前修飾、特殊メソッド、数値区切りなど、用途ごとに意味が変わります。
今回は、実務でよく使うPythonの_の使い分けを整理してみました。
_は用途によって意味が変わる
Pythonで使われる_は、文脈によって意味が変わります。
代表的な用途として次のようなものがあります。
- 変数名で使う
_(未使用を示す) - 先頭に付ける
_name(外部から使わない想定の内部用変数・メソッドを示す) - 先頭に2つ付ける
__name(クラス内で名前衝突を防ぐための名前修飾) - 前後に2つ付ける
__name__(特殊メソッド/属性) - 数値を読みやすくするための区切り(
1_000_000) - インタラクティブシェルで直前の計算結果を保持する変数
_ - i18n(国際化)で翻訳関数の別名として使う
_()
1. 未使用変数としての_
ループやアンパックで「値は使わないけど構文上必要」なときに_を使います。
# 3回だけ繰り返したいがループ変数は使わない
for _ in range(3):
print("hello")
# タプルの2番目は使わない
name, _, age = ("yamada", "unused", 30)
print(name, age)
unused_valueのように変数名を書くより、
_のほうが「この値は未使用」という意図がすぐ伝わります。
2. 先頭_nameは「内部利用」のサイン
_nameは、外部公開を想定しない属性・関数に付ける慣習です。
class UserService:
def __init__(self):
self._cache = {}
def _build_cache_key(self, user_id: int) -> str:
return f"user:{user_id}"
ここで大事なのは、アクセス禁止ではなく慣習という点です。
Pythonには厳密なprivate属性はないため、_nameは外部からアクセスすることも可能です。
3. __nameは名前修飾(Name Mangling)
クラス内で__nameのように先頭に2つ付けると、Python内部で名前が変換されます。
class Account:
def __init__(self):
self.__token = "secret"
acc = Account()
# print(acc.__token) # AttributeError
print(acc._Account__token) # このようにするとアクセスできる
これは完全なprivate化ではなく、
サブクラスとの名前衝突や、意図しないオーバーライドを避ける目的で使われます。
4. __name__は特殊メソッド/属性(dunder)
__init__, __len__, __str__のように前後に2つのアンダースコアが付いた名前は、Pythonのオブジェクトで特別な意味を持つメソッドです。
この形式はdunder(double underscore) と呼ばれることがあります。
class Item:
def __init__(self, name: str):
self.name = name
def __str__(self) -> str:
return f"Item(name={self.name})"
len(obj) # obj.__len__()が呼ばれる
str(obj) # obj.__str__()が呼ばれる
自分で勝手なdunder名を作るより、既存仕様に沿って使うのが基本です。
5. 数値リテラルの_区切り
_は数値を読みやすく区切る用途でも使えます。
値自体は変わりません。
total_users = 1_000_000
file_size = 10_485_760
桁数が大きい定数は、_区切りにするだけで読み間違いを減らせます。
6. 補足: REPLの_とi18nの_()
REPLでは直前の結果を保持
Pythonを対話モード(ターミナルでPythonを起動して1行ずつ実行するモード)で使うと、
直前の計算結果が _ に自動的に保存されます。
>>> 10 + 20
30
>>> _ * 2
60
i18nでは翻訳関数の別名で使う
アプリを多言語対応(国際化)するとき、文字列を翻訳する関数として_()が使われることがあります。
from gettext import gettext as _
_("Hello")
まとめ
今回は、Pythonの_活用方法をまとめてみました。
_は小さい記号ですが、用途ごとに意味を理解して使い分けると、コードの意図が伝わりやすくなり、レビューもしやすくなります。
ご拝読ありがとうございました。
参考リンク
- Python Docs: Tutorial(対話モードの
_について)
- PEP 8 – Style Guide for Python Code
- PEP 515 – Underscores in Numeric Literals
- gettext
