python3.13のリリースが近づいてきたということで、今回は各バージョンの便利機能をおさらいしたいと思います。
ちなみにPython3.13は現在candidate版が公開されています。candidate版は正式版になる予定のバージョンのことです。
Actual:
3.13 development begins: Monday, 2023-05-22
3.13.0 alpha 1: Friday, 2023-10-13
3.13.0 alpha 2: Wednesday, 2023-11-22
3.13.0 alpha 3: Wednesday, 2024-01-17
3.13.0 alpha 4: Thursday, 2024-02-15
3.13.0 alpha 5: Tuesday, 2024-03-12
3.13.0 alpha 6: Tuesday, 2024-04-09
3.13.0 beta 1: Wednesday, 2024-05-08 (No new features beyond this point.)
3.13.0 beta 2: Wednesday, 2024-06-05
3.13.0 beta 3: Thursday, 2024-06-27
3.13.0 beta 4: Thursday, 2024-07-18
3.13.0 candidate 1: Thursday, 2024-08-01
Expected:3.13.0 candidate 2: Tuesday, 2024-09-03
3.13.0 final: Tuesday, 2024-10-01
引用:https://peps.python.org/pep-0719/
また、1年以上前になりますが、JETBRAINSが2023年7月時点でのバージョン別利用度を公開しており、約4人に1人が最新バージョンを使用しているという結果になったそうです。
引用:https://www.jetbrains.com/ja-jp/lp/devecosystem-2023/python/
python 3.8
python3.7以前のバージョンはサポートが終了しているため、3.8以降のバージョンでピックアップしました。
引用:https://devguide.python.org/versions/
セイウチ演算子
python3.8でセイウチ演算子が使えるようになりました。
コードをスッキリ書くことができて、取得したデータに対して分岐させるときなどに便利です。
セイウチ演算子なし
s = 'python'
n = len(s)
if n > 5:
print(str(n) + "文字でした。5文字より多いです。")
else:
print(str(n) +"文字でした。5文字以下です。")
# 6文字でした。5文字より多いです。
セイウチ演算子あり
s = 'python'
if (n := len(s)) > 5:
print(str(n) + "文字でした。5文字より多いです。")
else:
print(str(n) +"文字でした。5文字以下です。")
# 6文字でした。5文字より多いです。
f-stringでデバッグが便利に
f-stringでデバッグに便利な機能が追加されました。{}の変数名のあとに=を書くと、変数名とその値が出力されます。
year = 2023
place = 'Tokyo'
print(f'{year=}, {place=}')
# year=2023, place='Tokyo'
位置専用引数
python3.8で位置専用引数が実装されました。位置専用引数は/
より前に置かれます。
def pos_only(arg, /):
print(arg)
#pos_only(2)
# 2
pos_only(arg = 5)
# TypeError: pos_only() got some positional-only arguments passed as keyword arguments: 'arg'
位置専用引数を活用することで、位置引数と任意個数のキーワード引数の衝突を防げます。
def func(a, **word):
print(a)
print(word)
func(0, a = 1, b = 2, c = 3)
# TypeError: func() got multiple values for argument 'a'
def func(a, /, **word):
print(a)
print(word)
func(0, a = 1, b = 2, c = 3)
# 0
# {'a': 1, 'b': 2, 'c': 3}
python 3.9
辞書の結合
辞書を|
演算子で結合できるようになりました。
d1 = {'k1': 1, 'k2': 2}
d2 = {'k3': 3, 'k4': 4}
d = d1 | d2
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4}
d3 = {'k5': 5, 'k6': 6}
d = d1 | d2 | d3
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4, 'k5': 5, 'k6': 6}
重複するキーがある場合は右側の値で上書きされます。
d1 = {'k1': 1, 'k2': 2}
d2 = {'k1': 10, 'k3': 3, 'k4': 4}
d = d1 | d2
print(d)
# {'k1': 10, 'k2': 2, 'k3': 3, 'k4': 4}
python 3.10
zip関数が使いやすくなった
zip関数にstrict引数が追加されました。strict=Trueにすると、引数の要素数が異なる場合、ValueErrorが発生します。
nums = [1, 2]
values = ['A']
zipped = list(zip(nums, values, strict=True))
print(zipped)
# ValueError: zip() argument 2 is shorter than argument 1
strict引数がない場合、多い分は無視されます。
nums = [1, 2]
values = ['A']
zipped = list(zip(nums, values))
print(zipped)
# [(1, 'A')]
match文の実装
python3.10からの新機能として、match文が導入されました。match文を使った方がif文よりスッキリ書ける場合があります。
error_code = 400
match error_code:
case 400:
print("Bad request")
case 404:
print("Not found")
case 418:
print("I'm a teapot")
case _:
print("Something's wrong with the internet")
# Bad request
error_code = 400
if error_code == 400:
print("Bad request")
elif error_code == 404:
print("Not found")
elif error_code == 418:
print("I'm a teapot")
else:
print("Something's wrong with the internet")
# Bad request
最後のブロック_
はワイルドカードの働きをし、マッチに絶対失敗しません。また、マッチするケースがない場合、そのブロックは実行されません。
python 3.11
例外処理がより便利に
例外にadd_note()メソッドが追加されました。これにより、例外を受け取ったあとに情報を追加することができます。
try:
raise TypeError('bad type')
except Exception as e:
e.add_note('Add information1')
e.add_note('Add information2')
raise
# TypeError: bad type
# Add information1
# Add information2
処理速度の向上
また、これは便利機能ではありませんが、Python3.11はPython3.10とくらべて10-60%高速になっています。平均的には、1.25倍の高速化を計測したとのことです。
python 3.12
エラーメッセージの改善
Python3.12ではエラーメッセージが改善されています。これは初学者の方にとって嬉しい改善です。
もしかしてインポートを忘れている?
標準ライブラリをインポートせずに使った場合、「もしかしてインポートを忘れている?」と表示されるようになりました。
python3.11以前
# import sys
sys.path
# NameError: name 'sys' is not defined
python3.12
# import sys
sys.path
# NameError: name 'sys' is not defined. Did you forget to import 'sys'?
名前間違えた?
from b import a
でaの名前を間違えてImportErrorが発生した場合、使用可能な名前を提案してくれます。
python3.11以前
from pprint import print
# ImportError: cannot import name 'print' from 'pprint'
python3.12
from pprint import print
# ImportError: cannot import name 'print' from 'pprint'. Did you mean: 'pprint'?
f-stringのクォーテーション
f-stringの囲みに使ったクォーテーション記号を{}内でも使えるようになりました。
python3.11以前
fruits = ['apple', 'banana', 'kiwi']
print(f"These are the names of fruits: {", ".join(fruits)}")
# SyntaxError: f-string: expecting '}'
python3.12
fruits = ['apple', 'banana', 'kiwi']
print(f"These are the names of fruits: {", ".join(fruits)}")
# These are the names of fruits: apple, banana, kiwi
また、これによって任意の数のf-stringをネストできるようになりました。(使う?)
# 任意の数ネストできる
f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}"
# 今までは4つが限界でした
f"""{f'''{f'{f"{1+1}"}'}'''}"""
さいごに
最後までお読みいただきありがとうございました。
zennにて「Python 基礎文法の教科書」を執筆しました。
基礎をきちんと学びたい方におすすめの書籍となっています。
また、YouTubeでPython3エンジニア認定基礎試験の解説もしています。