Pythonで知ってるとドヤ顔ができるかもしれない文法をいくつか紹介します

新しめの機能を中心に知っているとドヤ顔できるかもしれないpythonの文法を紹介します。

## 1. 代入式
python3.8より追加された新しい構文です。新しいものを知っているって良いですよね。
代入式は `:=`という構文で書き、条件式と代入文を同時に使用可能です。

例えば以下のような良くある条件式は

```py
text = 'Hello New Expression!!'
text_length = len(text)
if text_length > 10:
    print(f"String is too long!!({text_length} length, expected <= 10)")
```

`:=`を使用して以下のよう短縮して書くことが可能です。 
`if (text_length := len(text)) > 10:`の部分で代入と条件式の両方の役割を果たしていることが分かります。

```py
text = 'Hello New Expression!!'
if (text_length := len(text)) > 10:
    print(f"String is too long!!({text_length} length, expected <= 10)")
```

refs
代入式: https://www.python.org/dev/peps/pep-0572/

## 2. リスト以外の内包表記
よくある内包表記は以下のようなリストを生成するものだと思います。

```py
numbers = [1,2,3]
dubble_numbers = [x*2 for x in numbers]
print(dubble_numbers)
#[2, 4, 6]
```

あまり使われないですが、辞書、集合、ジェネレータの内包表記も存在します。これはドヤ顔ポイントですね。

- 辞書内包表記

`{}`内の`x:x*2`のようにkey-valueを書くと辞書が生成されます。

```py
numbers = [1,2,3]
dubble_number_dict = {x:x*2 for x in numbers}
print(dubble_number_dict)
#{1: 2, 2: 4, 3: 6}
```

- 集合内包表記

`{}`内で`x`のようにvalueのみを書くと集合が生成されます。

```py
numbers = [1,2,3,1,1]
dubble_number_set = {x for x in numbers}
print(dubble_number_set)
# set([1, 2, 3])
```

- ジェネレータ式

`()`内でリスト内包表記のような書き方をするとtupleではなくジェネレータが生成されます。

```py
numbers = [1,2,3]
dubble_number_generator = (x for x in numbers)
print(dubble_number_generator)
# <generator object <genexpr> at 0x10d7779b0>
```

refs
データ構造:　https://docs.python.org/3.9/tutorial/datastructures.html

## 3. 型ヒント
python3.5より静的型付け言語のようにコード内で型を宣言(正確には注釈)することが可能です。
動的型付け言語のメリットを捨てているような気もしますが、込み入った開発になってくると明示的に型が宣言されていないと保守的に不安になる方も多いと思います。
使用する上での注意点は
  - コメントアウトと同値、異なる型を代入してもエラーにならない。
  - 標準機能に型チェック機能はないので、ツールと併用。
このあたりをさらっとドヤ顔で説明できると良いですよね。

具体的なソースコードは以下になります。
保守性は上がるが、あくまでコメントの拡張機能であり実行時にはチェックされないことポイントです。
`text: str = 123 # Assignment int`もエラーなく通ります。

```py
def greeting(name: str) -> str:
    return f'Hello {name}'

text: str = 'Python!!'
print(greeting(text))
# Hello Python!!

text: str = 123 # Assignment int
print(greeting(text)) # No error
# Hello 123
```

標準ではチェックツールが提供されていないので外部のツールを使用する必要があります。
おそらく一番有名なのは `mypy`だと思われます。 http://www.mypy-lang.org/

他にもユーザー定義クラス等を型ヒントで宣言する方法など色々とルールがありますが、ここでは割愛します。

refs:
型ヒント: https://docs.python.org/3.9/library/typing.html

## 4. dataclass
python3.7より追加されたデータオブジェクトです。
web系などの開発の際にインターフェースを定義する時などに役立つドヤ顔機能です。
これを使うためにpython3.7にupdateしても良いレベルで私は好きな機能です。
- `@dataclass`デコレータをつけてclassの宣言をする。
- 従来までの `__init__`などの特殊メソッドを使用した冗長な書き方を簡略化。(正しくはデコレーターが特殊メソッドを生成)

具体的な使用例は以下のような形になります。

```py
from dataclasses import dataclass,asdict,astuple

@dataclass
class Person:
    name: str
    age: int = 0

    def greeting(self) -> str:
        return f"My name is {self.name}, {self.age} years old."

tanaka = Person('tanaka',18)
print(tanaka.greeting())
# My name is tanaka, 18 years old.

baby = Person('taro') # Use default value
print(baby.greeting())
# My name is taro, 0 years old.

print(asdict(baby)) # To dict object 
# {'name': 'taro', 'age': 0}

print(astuple(baby)) # To tuple object
# ('taro', 0)
```
イミュータブルなオブジェクトにする方法や `__post_init__`による初期化処理の拡張などの機能もありますがここでは割愛。

refs:
dataclass: https://docs.python.org/3/library/dataclasses.html

## 5. f文字列 
python3.6より追加された文字列テンプレートです。

以前からあった文字列メソッドの `format()`や `%演算子`と比べて簡略化されており、かつ高機能になっています。
具体的には文字列のはじめに`f""`を置いて以下のように使用します。

```py
a,b = 1000,2000
print(f'a is {a},b is {b}')
# a is 1000,b is 2000

print(f'sum of ab is {a+b}') # can be calculated
# sum of ab is 3000

print(f'a: {a:,}') # separated by comma
# a: 1,000
```

上記のように文字列内での計算が可能になった点や柔軟な書式設定が可能になった点がドヤ顔できるポイントです。

またpython3.8からは変数のデバッグ用に機能が拡張されています。

```py
a,b = 1000,2000
print(f'a={a},b={b}') # before 3.8
# a=1000,b=2000

print(f'{a=},{b=}') # after 3.8
# a=1000,b=2000
```
変数の後に`=`を差し込むことで変数の値と名前の両方が出力されていることが分かります。

refs:
フォーマット: https://docs.python.org/3/tutorial/inputoutput.html
デバッグ可能に: https://docs.python.org/3/whatsnew/3.8.html#f-strings-support-for-self-documenting-expressions-and-debugging

## まとめ
現場で仕事をしているとpython2などの過去の負債が残っていてなかなか使うのは難しい、、、と思いつつ新しい機能にワクワクしながらドヤ顔で改修して行きたいところですね。