Python 3.9にして嬉しかったこと2選

この記事は[MDC Advent Calendar 2020](https://qiita.com/advent-calendar/2020/mdc) 23日目の記事です。
2020年12月23日は平日です。
え？素数の話やめたって？はい、そろそろ飽きてきたかなと（ちなみに直近だと素数は20201227です）。
あと平日とか知ってたって？あらら、それは失礼しました。

# はじめに
再びお送りする、n選シリーズです。今度はPythonについてですね。しかも5選から2選に減ってます。もはや「選」とは・・・。
先日Macをリカバリした際にPythonのバージョンも一番最新のものにしたらテンションが少し上がったのでそのノリで書きます。
あくまで私の目線で嬉しかったことなので人によってはもっと違うことで喜びを感じるかと思われますが、そこは個人差ということでお願いします。

# PEP616: 接頭辞と接尾辞の消去
文字列の先頭もしくは末尾の文字列を除くメソッドが追加されました。
これまでだと、正規表現を使ってやるのが手っ取り早い手段だったと思いますが、`removeprefix()` もしくは `removesuffix()` で簡単にできちゃいます。

## これまでの方法
```python
>>> sample = 'test_sample_string'
>>> sample
'test_sample_string'
>>> import re
>>> re.sub('^' + re.escape('test_'), '', sample)
'sample_string'
>>> re.sub(re.escape('_string') + '$', '', sample)
'test_sample'
```

はい、普通に正規表現という感じですね。

## 今回追加された方法

```python
>>> sample = 'test_sample_string'
>>> sample
'test_sample_string'
>>> sample.removeprefix('test_')
'sample_string'
>>> sample.removeprefix('test_sample_')
'string'
# いうまでもなく先頭の文字列という条件を満たしてたらどこまででもOK
>>> sample.removeprefix('sample_')
'test_sample_string'
# 先頭の文字列として一致しないとダメ
>>> sample.removesuffix('_string')
'test_sample'
>>> sample.removesuffix('test')
'test_sample_string'
# prefixと同様
```

## その他

ちなみに日本語も試してみたらいけました。やったね。

```python
>>> sample2 = '赤パジャマ青パジャマ黄パジャマ'
>>> sample2
'赤パジャマ青パジャマ黄パジャマ'
>>> sample2.removeprefix('赤パジャマ')
'青パジャマ黄パジャマ'
>>> sample2.removesuffix('黄パジャマ')
'赤パジャマ青パジャマ'
```

# PEP584: 辞書の結合
2つの辞書を結合するには新しく結合先の辞書を用意してからupdate()で頑張るしかなかったですが、今回からは演算子で可能だそうです。
具体的には、`dic1 | dic2`で簡単にできちゃうみたいです。

## これまでの方法

```python
>>> airport1 = {'HND': 'Tokyo', 'KIX': 'Osaka', 'NGO': 'Nagoya'}
>>> airport2 = {'NRT': 'Tokyo', 'ITM': 'Osaka', 'CTS': 'Sapporo'}
>>> airport = airport1.copy()
>>> airport
{'HND': 'Tokyo', 'KIX': 'Osaka', 'NGO': 'Nagoya'}
>>> airport.update(airport2)
>>> airport
{'HND': 'Tokyo', 'KIX': 'Osaka', 'NGO': 'Nagoya', 'NRT': 'Tokyo', 'ITM': 'Osaka', 'CTS': 'Sapporo'}
```
う〜んたしかにめんどくさい・・・。

## 今回追加された方法

```python
>>> airport1 = {'HND': 'Tokyo', 'KIX': 'Osaka', 'NGO': 'Nagoya'}
>>> airport2 = {'NRT': 'Tokyo', 'ITM': 'Osaka', 'CTS': 'Sapporo'}
>>> airport1 | airport2
{'HND': 'Tokyo', 'KIX': 'Osaka', 'NGO': 'Nagoya', 'NRT': 'Tokyo', 'ITM': 'Osaka', 'CTS': 'Sapporo'}
# 2つの辞書を結合
>>> airport = airport1 | airport2
# 当然、新しい辞書にぶちこめます
>>> airport
{'HND': 'Tokyo', 'KIX': 'Osaka', 'NGO': 'Nagoya', 'NRT': 'Tokyo', 'ITM': 'Osaka', 'CTS': 'Sapporo'}
>>> airport['NRT']
'Tokyo'
```

## その他
地味に`|`に対応する代入演算子の `|=` にも対応しています。

```python
>>> airport1
{'HND': 'Tokyo', 'KIX': 'Osaka', 'NGO': 'Nagoya'}
>>> airport2
{'NRT': 'Tokyo', 'ITM': 'Osaka', 'CTS': 'Sapporo'}
>>> airport1 |= airport2
>>> airport1
{'HND': 'Tokyo', 'KIX': 'Osaka', 'NGO': 'Nagoya', 'NRT': 'Tokyo', 'ITM': 'Osaka', 'CTS': 'Sapporo'}
```

for文とかぶん回すときに使えそうですね。

## その他

ちなみにキーが被った場合は、updateで実現してたときと同じく後に指定（`dic1 | dic2`でいうと`dic2`）したほうが優先されるみたいです。

```python
>>> code1 = {'Tokyo': 'HND', 'Osaka': 'KIX', 'Nagoya': 'NGO'}
>>> code2 = {'Tokyo': 'NRT', 'Osaka': 'ITM', 'CTS': 'Sapporo'}
>>> code1 | code2
{'Tokyo': 'NRT', 'Osaka': 'ITM', 'Nagoya': 'NGO', 'CTS': 'Sapporo'}
>>> code2 | code1
{'Tokyo': 'HND', 'Osaka': 'KIX', 'CTS': 'Sapporo', 'Nagoya': 'NGO'}
```

# おまけ 
毎度おなじみのおまけです（そんなにおなじみでもないとかいうツッコミもありそうですね）。

## pyenv(anyenv) をアップグレードする

```shell
git clone git://github.com/yyuu/pyenv-update.git ${PYENV_ROOT}/plugins/pyenv-update
```
でプラグインいれたら一発OKだったんですね・・・。
ずっと知らなかった・・・（毎回毎回git pullしてました）。

# 最後に
[リリースノート](https://docs.python.org/3.9/whatsnew/3.9.html)を見たらもっと色々ありましたね。
いかに私の利用用途が限定的か・・・。
ではではEnjoy Python!