Pythonでは、変数名に記号(アスタリスクやアンダースコア)を付けることで、特別な意味を持たせることがあります。
また、リストや辞書を扱うときにも記号が使われます。
この記事では、記号を使った代表的な変数や表現を、初心者向けにわかりやすくまとめます!
* を使ったリスト・タプルのアンパック
*リスト
の形で使うと、リストやタプルの中身をバラして渡すことができます。
これを「アンパック」と呼びます。
lst = [1, 2, 3]
print(*lst)
出力:
1 2 3
このように、リストの中身が展開されて出力されます。
また、関数定義側で *args
を使うと、渡された複数の引数を**まとめる(パックする)**ことができます。
例:
def func(*args):
print(args)
func(1, 2, 3)
出力:
(1, 2, 3)
関数定義で仮引数に *
を付けた場合、まとめる(パック)動きになります。
名前は自由ですが、慣例として args
がよく使われます。
** を使った辞書のアンパック
**辞書
の形で使うと、辞書のキーと値をバラしてキーワード引数として渡すことができます。
def greet(name, age):
print(f"{name} is {age} years old.")
info = {'name': 'Alice', 'age': 25}
greet(**info)
出力:
Alice is 25 years old.
また、関数定義側で **kwargs
を使うと、渡された複数のキーワード引数を**まとめる(パックする)**ことができます。
例:
def func(**kwargs):
print(kwargs)
func(name='Alice', age=25)
出力:
{'name': 'Alice', 'age': 25}
関数定義で仮引数に **
を付けた場合、まとめる(パック)動きになります。
こちらも名前は自由ですが、慣例として kwargs
がよく使われます。
_変数(先頭に1つのアンダースコア)
先頭にアンダースコア _
を付けた変数は、
「これはクラス内部用ですよ」「外部から直接触らないでね」という慣習的なサインです。
アクセスは禁止されていませんが、開発者間のマナーとして守るべきものです。
class Parent:
def __init__(self):
self._secret = 'hidden'
class Child(Parent):
def show(self):
print(self._secret)
c = Child()
print(c._secret) # 外部からもアクセスできるが、基本的には触らない
c.show()
出力:
hidden
hidden
サブクラスからもアクセス可能ですが、外部からのアクセスは避けるべき、という意図があります。
__変数(先頭にダブルアンダースコア)
先頭にダブルアンダースコア __
を付けた変数は、
クラス内部専用にしたい意図を持たせた、プライベートっぽい変数です。
Pythonでは「名前マングリング」という仕組みにより、外部から直接アクセスしにくくなります。
class Sample:
def __init__(self):
self.__secret = 'hidden'
s = Sample()
# print(s.__secret) # エラー!
print(s._Sample__secret) # 実際にはこうアクセスできる
出力:
hidden
名前マングリングとは
変数名を自動的に _クラス名__変数名
という形に変換して隠す仕組みです。
(つまり、__secret
という変数名は、クラス名が Sample
なら内部的に _Sample__secret
に変換されます)
完全なアクセス防止ではありませんが、うっかり触るリスクを減らすための工夫です。
__変数__
(前後にダブルアンダースコア)
前後にダブルアンダースコアが付いた __xx__
の形式は、
Python内部で使われる特殊なメソッドや属性です。
代表例:
-
__init__
:インスタンス生成時に呼び出されるコンストラクタ -
__str__
:オブジェクトを文字列として表現する -
__len__
:オブジェクトの長さを取得する
class MyClass:
def __init__(self):
print('Constructor called')
obj = MyClass()
出力:
Constructor called
こうした特殊メソッドはPython内部仕様のため、
自作で新しい __xx__
形式の名前を作るのは基本的に推奨されません。
_(アンダースコア1文字)【一般用途:無視する変数】
この変数は一時的に使わない・無視してよいことを明示するためのサインです。
for _ in range(3):
print('Hello')
出力:
Hello
Hello
Hello
ループ変数を使わない場合に、_を使って「無視する」ことを表現しています。
注意
- 実際には
_
にも値(ここではループカウンタ)が入っています。 - ただし、使わないことを明示する目的で
_
を使っています。
_(アンダースコア1文字)【対話モード】
Pythonの対話モード(REPL)では、直前の評価結果が自動的に _
に保存されます。
>>> 2 + 3
5
>>> _ * 2
10
ここで _
は直前の結果 5 を指しています。
通常のPythonスクリプトではこの挙動はありません。
あくまで対話モード(PythonシェルやJupyter Notebook)特有の機能です。
まとめ
書き方 | 意味 |
---|---|
*リスト | リストやタプルをバラして渡す(アンパック) |
**辞書 | 辞書をキーワード引数にして渡す(アンパック) |
_変数 | クラス内部用(プロテクト的な意味合い) |
__変数 | クラス内部専用(名前マングリングによる隠蔽) |
変数 | 特殊なメソッド・属性(Python内部仕様) |
_(一般) | 無視する変数 |
_(対話モード) | 直前の結果を保持する(REPL専用機能) |
記号を使った変数や表現を理解すると、Pythonのコードを読む力がぐっと上がります!
ぜひこの機会に整理して覚えておきましょう。