[アップデート] AWS Lambda でPython3.9ランタイムサポート!ついでに変更点もおさらいしよう

2021.08.17

大阪オフィスの小倉です。

本日のアップデートで、LambdaランタイムにPython3.9がサポートされました!

マネジメントコンソール上でもPython3.9が選択できるようになっています

Python3.9自身は2020年の10月にリリースされていますが、Lambdaのサポートに伴ってPython3.9でLambdaを書くことが増えると思うので、今更ではありますがPython3.9で追加された機能をおさらいしようと思います。

Python3.9での主な変更をおさらい

辞書のマージと代入

| 演算子で辞書のマージができるようになりました。新しい辞書オブジェクトが返されます。

dict_1 = {'key': 'value'}
dict_2 = {'hoge': 'fuga'}
dict_3 = {'key': 'value2'}

print(dict_1 | dict_2) # {'key': 'value', 'hoge': 'fuga'}
print(dict_1 | dict_3) # {'key': 'value2'}

同一のkeyが同じ場合は、右辺の値(value2)が採用されています

これまでは以下の書き方でした

dict_1 = {'key': 'value'}
dict_2 = {'hoge': 'fuga'}
dict_3 = {'key': 'value2'}

# その1
new_dic = {}
new_dic.update(dict_1)
new_dic.update(dict_2)
print(dic_new) # {'key': 'value', 'hoge': 'fuga'}

# その2
print(
    dict(
        **dict_1,
        **dict_2
    )
) # {'key': 'value', 'hoge': 'fuga'}

# 同一keyがある場合はエラーになってしまう
# print(
#     dict(
#         **dict_1,
#         **dict_3
#     )
# )

|=演算子で代入ができます。以前からあるupdateと同じ動きですね。

dict_1 = {'key': 'value'}
dict_2 = {'hoge': 'fuga'}
dict_3 = {'key': 'value2'}

dict_1 |= dict_2
print(dict_1) # {'key': 'value', 'hoge': 'fuga'}
dict_1 |= dict_3
print(dict_1) # {'key': 'value2', 'hoge': 'fuga'}

これまで私は以下の書き方でした

dict_1.update(dict_2)
print(dict_1) # {'key': 'value', 'hoge': 'fuga'}
dict_1.update(dict_3)
print(dict_1) # {'key': 'value2', 'hoge': 'fuga'}

プレフィックス/サフィックスの削除

文字列に対して、removeprefix()でプレフィックス(先頭の文字列)を、removesuffix()でサフィックス(末尾の文字列)を削除できます

name = 'cm-ogura-test'

new_name = name.removeprefix('cm-')
print(new_name) # ogura-test

new_name_2 = name.removesuffix('-test')
print(new_name_2) # cm-ogura

これまで私は以下の様に書いていました

# スライスで削除する
new_name = name[3:]
print(new_name) # ogura-test

new_name_2 = name[:-5]
print(new_name_2) # cm-ogura

# 空白で置換する(が先頭末尾以外も置き換えてしまう)

new_name_3 = name.replace('cm-', '')
print(new_name_3) # ogura-test

スライスの数値指定を混乱しがちな私にはすごくありがたいです。

組み込みGeneric型

型ヒントを使って、intを格納するlistを定義するときに、typingモジュールを使わずに済むようになりました。

li_test: list[int] = [1, 2, 3, 4, 5]

これまでは以下の様に書いていました

from typing import List
li_test: List[int] = [1, 2, 3, 4, 5]

listListが混在していたのが、スッキリ書けるようになっています。set,dict,tupleなんかも対応しているようです

ZoneInfoモジュール

タイムゾーン情報を、タイムゾーン名から作れるようになっています

from datetime import datetime
from zoneinfo import ZoneInfo

jst = ZoneInfo("Asia/Tokyo")
now = datetime(2011, 1, 1, 12, 0, 0, tzinfo=jst)
print(now) # 2011-01-01 12:00:00+09:00

これまで私は以下の様に書いていました

from datetime import datetime, timedelta, timezone

jst = timezone(timedelta(hours=9))
now = datetime(2021, 8, 14, 10, 0, 0, tzinfo=jst)
print(now)

その他

個人的にオッと思ったのが、math.gcdのアップデートと、math.lcmの追加です。

math.gcdは最大公約数を取得できますが、これまで引数に2つしか渡せませんでした。Python3.9では3つ以上の引数を指定して、最大公約数を求めることが出来ます。

math.lcmは最小公倍数を取得できます。

import math

print(math.gcd(5, 20, 100)) # 5

他にも変更点はあるので、興味がある方は公式ドキュメントで確認してみてください。

Lambdaで動かす

さて、新しいLambdaのランタイムで動作するか確認してみましょう。

とりあえず上記を雑に詰め込んで動かしてみます。

import json
from datetime import datetime
from zoneinfo import ZoneInfo


def lambda_handler(event, context):
    print(sys.version_info)
  
    dict_1 = {'key': 'value'}
    dict_2 = {'hoge': 'fuga'}
    dict_3 = {'key': 'value2'}

    # 辞書のマージ
    print(dict_1 | dict_2)

    # 辞書の代入
    dict_1 |= dict_3
    print(dict_1)

    name = 'cm-ogura-test'

    # プレフィックスの削除
    new_name_1 = name.removeprefix('cm-')
    print(new_name_1)

    # サフィックスの削除
    new_name_2 = name.removesuffix('-test')
    print(new_name_2)


    # 組み込みGeneric型
    li_test: list[int] = [1, 2, 3, 4, 5]
    print(li_test)

    # ZoneInfo
    new_jst = ZoneInfo("Asia/Tokyo")
    now = datetime(2011, 1, 1, 12, 0, 0, tzinfo=new_jst)
    print(now)

    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
sys.version_info(major=3, minor=9, micro=6, releaselevel='final', serial=0)
{'key': 'value', 'hoge': 'fuga'}
{'key': 'value2'}
ogura-test
cm-ogura
[1, 2, 3, 4, 5]
2011-01-01 12:00:00+09:00

無事に動作することが確認できましたね

まとめ

普段Lambda向けにPythonを書くことがほとんどだったので、ほぼ自分向けにPython3.9の変更点をおさらいしてみました。

Python自身はもうすぐ3.10がリリースされるので、そちらも待ち遠しいですね。

参考

以下のサイトを参考にさせていただきました