Pythonで関数の引数にタプルを直接定義できないのはなぜ?PEP 3113による仕様変更と対処法を解説
Python 3.0以降、関数の引数でタプルを直接展開できなくなった理由
Python 3.0以降では、PEP 3113(タプルパラメータの削除)により、関数定義時に引数としてタプルを直接展開して受け取ることができなくなりました。
そのため、以下のように引数内でタプルを括弧で囲んで定義しようとすると、構文エラーが発生します。
def fn(a,(b,c)):
passこのコードを実行すると、Pythonインタプリタはタプルの最初の括弧の位置でSyntaxErrorを表示します。これは記述ミスではなく、言語仕様として意図的に廃止された機能だからです。
廃止された背景
かつてのPython 2系では、引数リストの中でタプルを自動的にアンパックする「タプルパラメータ」が利用可能でした。しかし、この記法は関数シグネチャの解析を複雑にし、可読性やツールによる静的解析の妨げになるという指摘がありました。そこでPEP 3113によってこの機能は削除され、より明示的な方法でのみタプルを受け取る設計に統一されました。
正しい代替方法:関数内でアンパックする
代わりに、タプルオブジェクトをそのまま引数として渡し、関数の内部でアンパックするのが標準的な書き方です。
次のコードでは、2つの点のx座標・y座標を表すタプルを引数として渡し、2点間の距離(斜辺の長さ)を計算しています。計算前に、それぞれのタプルをx座標とy座標に分解しています。
def hypot(p1, p2):
x1, y1 = p1
x2, y2 = p2
import math
hyp = math.sqrt((x1 - x2)**2 + (y1 - y2)**2)
return hyp
x = (10, 10)
y = (20, 20)
print("hyp=", hypot(x, y))実行結果:
hyp= 14.142135623730951
まとめ
- Python 3.0以降、関数の引数リスト内でタプルを直接展開する記法はPEP 3113により廃止された。
- 代わりに、タプルを引数として渡し、関数内で
x1, y1 = p1のようにアンパックするのが推奨される書き方。 - この方法なら、コードの可読性が向上し、型ヒントや静的解析ツールとも相性が良い。
-
実行時にPython関数を動的に定義・実行する方法
Pythonでは、標準ライブラリの types モジュールが提供する types.FunctionType() を利用することで、プログラムの実行時(ランタイム)に関数を動的に定義し、そのまま呼び出すことができます。 動的に関数を作成する手順 コード文字列から関数オブジェクトを生成するには、以下の手順を行います。 types モジュールをインポートします。 実行したいコードを文字列として用意し、組み込み関数 compile() でコードオブジェクトにコンパイルします。 コンパイル済みのコードオブジェクトと、グローバル名前空間となる辞書を types.FunctionType() に渡して、
-
Pythonタプル(tuple)入門:作成・操作・削除の基本をコード例で解説
Pythonにおけるタプル(tuple)は、順序付け(ordered)かつ変更不可(immutable)という特徴を持つコレクションです。変更不可であるため、一度作成したタプルに要素を追加したり削除したりすることはできません。 タプルは丸括弧 () と、最低1つのカンマ , を使って作成します。 また、タプルはリストと同じようにインデックス指定やスライシングが可能ですが、スライスの結果もタプルとして返される点に注意しましょう。 タプルの作り方 colorsTuple = (red, green, blue) print(colorsTuple) 実行結果: (red, green, blue