あまり知られていないPythonの言語仕様（Python3.4以降対応）

# はじめに

Pythonの言語仕様であまり知られていない（と勝手に思っている）ものをまとめてみる。

初級・中級・上級の分類は適当。

他にもあれば追記していく。

# 初級編

## 複素数リテラル

複素数の演算が標準でできるようになっている。
添字はiではなくjを使う。

```pycon
>>> c1 = 1 + 1j
>>> c2 = 1 - 2j
>>> c1 + c2
(2-1j)
>>> c1 * c2
(3-1j)
>>> c1 / c2
(-0.2+0.6j)
```

## 複数のfor..inを含む内包表記

内包表記の中にfor..inを複数書ける。

```pycon
>>> a = range(3)
>>> b = range(4)
>>> [x + y for x in a for y in b]
[0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5]
```

## n個おきのスライス

次のように書くことでリストなどの要素をn個おきに取り出せる。

```pycon
>>> a = list(range(20))
>>> a[::2]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
```

## スライスによるリストのコピー

スライス構文にインデックスを渡さなければリストのコピーを作れる。

```pycon
>>> a = range(10)
>>> b = a
>>> b
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> b is a # bとaは同一のオブジェクト
True
>>> c = a[:]
>>> c
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> c is a # bとaは別個のオブジェクト
False
```

# 中級編

## Ellipsis

`...` が「省略」を表すオブジェクトとして扱われる。
詳しくは[こちら](http://qiita.com/yubessy/items/cc1ca4dbc3161f84285e "Python3の...（Ellipsisオブジェクト）について")を参照。

```pycon
>>> ...
Ellipsis
>>> bool(...)
True
```


## キーワード限定引数

関数定義中で `*,` を書くと、以降の引数を必ずキーワード引数として呼び出さなければならないようにできる。

```pycon
>>> def f(a, *, b):
...     pass
...
>>> f(1)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: f() missing 1 required keyword-only argument: 'b'
>>> f(1,2)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: f() takes 1 positional argument but 2 were given
>>> f(1,b=2)
>>>
```

## 関数アノテーション

関数の引数と返り値にアノテーションをつけられる。
ドキュメントなどに使うためのアノテーションなので、違う型のオブジェクトが与えられてもエラーにはならない。

```pycon
>>> def f(x : int, y : int) -> int:
...     return x + y
...
>>> f(2, 3)
5
>>> f('hoge', 'fuga') # エラーにはならない
'hogefuga'
```

## global

`global` によって、どのスコープからでもグローバル変数を実行時に定義できる。

```pycon
>>> def f():
...     global a
...     a = 1
...
>>> a # ここではaは未定義
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'a' is not defined
>>> f() # fの呼び出しによりグローバル変数aが定義される
>>> a
1
```

## nonlocal

`nonlocal` によって、ひとつ外側のスコープに属する変数への代入が可能となる。
クロージャが簡単に作れる。

```pycon
>>> def make_counter():
...     count = 0
...
...     def counter():
...         nonlocal count
...         count += 1
...         return count
...
...     return counter
...
>>> c = make_counter()
>>> c(), c(), c()
(1, 2, 3)
```

# 上級編

## 引数付きデコレータ

「『関数を受け取って関数を返す関数』を返す関数」を書くことで引数付きデコレータが作れる。
Flaskの `@route('/')` などはこれを用いて実装されていると思われる。

```pycon
>>> def greet(before, after):
...      def decorator(func):
...          def wrapper(*args, **kwargs):
...              print(before)
...              func(*args, **kwargs)
...              print(after)
...          return wrapper
...      return decorator
...
>>> @greet('Hi.', 'Bye.')
... def introduce(name):
...     print('I am ' + name + '.')
...
>>> introduce('yubessy')
Hi.
I am yubessy.
Bye.
```

## クラスデコレータ

クラスをラッピングするデコレータを書くことができる。
以下は簡易シングルトンの実装例。

```pycon
>>> def singleton(cls):
...   instances = {}
...   def getinstance(*args, **kwargs):
...     if cls not in instances:
...         instances[cls] = cls(*args, **kwargs)
...     return instances[cls]
...   return getinstance
...
>>> @singleton
... class C(object):
...   pass
...
>>> c1 = C()
>>> c2 = C()
>>> c1 is c2
True
```

## yield from

他のイテレータから値を返すジェネレータを作れる。

```pycon
>>> def g():
...     yield from range(5)
...     yield from range(5, 10)
...
>>> [i for i in g()]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```

## raise from

例外を連鎖する際に、送出元の例外を保持する。

```
>>> try:
...     raise Exception('e1') from Exception('e2')
... except Exception as e:
...     print(e.__cause__)
...
e2
```

# 参考

* <http://qiita.com/yubessy/items/cc1ca4dbc3161f84285e>
* <http://stackoverflow.com/questions/1261875/python-nonlocal-statement>
* <http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python>
* <http://docs.python.jp/3/reference/simple_stmts.html#grammar-token-raise_stmt>