はじめに
Pythonにおいて、アンダースコア(_
)は、異なる文脈で頻繁に使用され、それぞれに異なる意味を持ちます。この記事では、Pythonにおけるアンダースコアの異なるユースケースについて説明します。
単一のアンダースコア (_)
Pythonにおいて、単一のアンダースコア(_
)は、プログラミングにおける変数として頻繁に使用されます。これは、"捨てられる"変数と呼ばれることが多く、その主な目的は、再利用されない値を保持することです。名前が軽視されるように見えるかもしれませんが、クリーンで効率的なPythonコードを書く上で重要な役割を果たしています。
以下は、アンダースコアを捨てられる変数として使用する場合がある例です。
値を無視
値を展開する場合、必要のない値に出くわすことがあります。名前空間を混乱させるだけの役に立たない変数を作成する代わりに、不要な値をアンダースコアに割り当てることができます。
a, _, c = (1, 2, 3 )
print(a, c) # Outputs: 1 3
この例では、タプル(1, 2, 3)
がa
、_
、およびc
に展開されています。 2番目の値は必要ないため、アンダースコアに割り当てられます。
特定の回数ループ
ループでは、ループ変数自体がループ内で使用されない場合、アンダースコアがよく使用されます。これは、特定の回数ブロックを繰り返し実行するループで特に一般的です。
for _ in range(3):
print("Hello, World!") # Outputs "Hello, World!" three times
ここでは、ループが単に3回"Hello, World!"
を出力しています。実際のループ変数は無関係であるため、アンダースコアが使用されます。
対話型インタプリタでの作業
Pythonの対話型インタプリタでは、アンダースコア変数には前回の操作の結果が自動的に割り当てられます。これは、PythonシェルまたはJupyterノートブックで作業する際に便利です。
>>> 10 + 20
30
>>> _
30
この例では、10と20の合計は30です。 _
が入力されると、前回の操作の結果が取得されます。
単一アンダースコアを接頭辞として使用 (_var)
Pythonにおいて、変数、関数、またはメソッドが単一のアンダースコアで始まる場合、他のプログラマーにその要素が内部使用を意図していることを明示する明確な信号となります。JavaやC++のような言語での「private」としての制限はないものの、直接的なアクセスを避けるように働きます。
クラスの変数とメソッド
クラス内の変数またはメソッドの前に単一のアンダースコアを付けると、これらの要素がクラス内部でのみ使用されることを示す慣例です。ただし、これらの要素は外部世界からもアクセスおよび変更できます。
次は、これが実際にどのように見えるかの例です。
class MySecretClass:
def __init__(self):
self._secret_attribute = 42
def _secret_method(self):
print("This is an internal method!")
この例では、 _secret_attribute
および_secret_method
は、MySecretClass
クラス内部で使用することを意図しています。ただし、Pythonは制限を強制しないため、これらの要素はクラスのオブジェクトからアクセスできます。
obj = MySecretClass()
print(obj._secret_attribute) # Outputs: 42
obj._secret_method() # Outputs: "This is an internal method!"
関数
クラス属性やメソッドと同様に、関数名の先頭に単一のアンダースコアが付いている場合、その関数が内部使用のためであることを示します。これは通常、モジュールのパブリックAPIの一部ではない関数であることを意味し、そのため直接アクセスされるべきではないとされます。
def _internal_function():
print("This function is for internal use.")
この例では、_internal_function
は、定義されているモジュール内で内部的に使用される関数です。クラス属性やメソッドと同様に、Pythonはこれを強制しないため、通常どおりに関数を呼び出すことができます。
単一のアンダースコアを接尾辞として使用 (var_)
Pythonにおいて、変数、関数、またはメソッド名に後続するアンダースコアを含む場合があります(例: var_
)。これは、Pythonのキーワードを変数名として使用できるようにする重要な目的を果たします。
Pythonには、言語の構文で特別な意味を持つため、変数名として使用できない予約語のセットがあります。これには、class
、def
、for
、if
、 while
などの単語が含まれます。
ただし、変数名としてPythonのキーワードを使用することが役立つ場合があるため、変数名に末尾にアンダースコアを追加して、キーワードとして使用できるようにすることができます。
次の例をご覧ください。
# This would cause a syntax error:
# class = 'Computer Science 101'
# But this is perfectly valid:
class_ = 'Computer Science 101'
この例では、class_
は、クラス名を表す文字列を保持する変数名として使用されています。class
はもっとも直感的な変数名であったかもしれませんが、Pythonでは予約語であるため、変数名として使用することはできません。そのため、代わりにclass_
が使用されます。
Pythonキーワードとの名前の競合を避けるために末尾にアンダースコアを使用する慣習は、Python言語によって強制されるルールではなく、コードの可読性と保守性を向上させるために設計された多くのPythonの慣習の1つです。
また、この慣習はPythonのキーワードとの競合を避けることができますが、組み込み関数名との競合には役立ちません。例えば、list_ = [1、2、3]
は有効なPythonコードですが、list
はPythonの組み込み関数であるため、混乱する可能性があるため、末尾にアンダースコアを使用する名前を避けることが最善です。
2つのアンダースコアを接頭辞として使用 (__var)
Pythonにおいて、変数、関数、またはメソッドが2つのアンダースコアで始まる場合(__var
)、名前マングリングと呼ばれるメカニズムがトリガされます。これは、単一アンダースコア接頭辞(_var
)とは異なるものです。名前マングリングは、サブクラスが誤ってプライベートメソッドや属性をオーバーライドしないようにする方法です。
名前マングリングの概念についてもう少し詳しく説明し、Pythonでどのように使用されるかを見てみます。
名前マングリング
名前マングリングとは、変数名を変更して、誤って取得または変更されることが少なくなるようにするメカニズムです。Pythonは完全にプライベート変数やメソッドの概念をサポートしていないため、変数またはメソッドが2つのアンダースコアで始まる場合、名前マングリングがトリガされます。
変数またはメソッドが2つのアンダースコアで始まる場合、Pythonはクラス名を接頭辞として変数名を変更し、誤ってアクセスまたは変更されることが少なくなります。
次の例をご覧ください。
class MyClass:
def __init__(self):
self.__private_var = "I am private"
変数__private_var
は名前マングリングの対象であり、クラスの外部では異なるものに見えます。
obj = MyClass()
print(obj.__private_var) # Outputs: AttributeError: 'MyClass' object has no attribute '__private_var'
名前マングリングに関する注意事項
名前マングリングはプライバシーの一定のレベルを提供できますが、完全ではありません。マングリングされた名前は、構文を知っている場合には直接アクセスできます。前の例から「プライベート」変数にアクセスする方法を以下に示します。
print(obj._MyClass__private_var) # Outputs: "I am private"
Pythonは、__private_var
の前に_MyClass
(アンダースコアとクラス名)を追加しました。
また、2つのアンダースコアが変数またはメソッド名の両方の接頭辞と接尾辞にある場合(__var__
)、名前マングリングは発生しません。このパターンは特別なメソッドに使用されます。
2つのアンダースコアを接頭辞と接尾辞として使用( __var__)
Pythonで2つのアンダースコアで囲まれたメソッド(__var__
)は、「dunder」メソッド(「double underscore」の略)と呼ばれます。これらのメソッドには特別な意味があり、名前マングリングの対象になりません。これらのメソッドは、特別なプロパティを持つため、「マジックメソッド」とも呼ばれます。
これらのdunderメソッドは、通常、組み込み型を模倣するために特定の動作を実装するために使用されます。もっとも一般的に使用されるdunderメソッドには、__init__
、__str__
、__len__
、および__getitem__
があります。
アンダースコアをインフィックスとして使用(var_var)
アンダースコアは、特に複数の単語変数、関数、またはメソッド名の可読性を向上させるために、名前の中で使用されます。これをスネークケースと呼び、Pythonで一般的に使用されています。
def calculate_average_score():
...
この関数では、アンダースコアがcalculate
、average
、score
の単語を区切っているため、読みやすくなっています。