Pythonの組み込み関数69個を制覇する 第2回 c～d

Pythonでは、非常に多くの組み込み関数(Built-in Functions)が用意されており、ライブラリをimportせずとも様々な処理を行うことができます。
基本に立ち返って、組み込み関数の使い方を整理して行きたいと思います。
尚、実行例はWindows Subsystem for LinuxのUbuntu18.04にインストールしたPython3.7.1で作成しています。

[Pythonの組み込み関数69個を制覇する 第1回 a～b](https://qiita.com/ichi_taro3/items/cd71a8e43040abb446a1)
[Pythonの組み込み関数69個を制覇する 第3回 e～g](https://qiita.com/ichi_taro3/items/c866b7124415464e8ef1)
[Pythonの組み込み関数69個を制覇する 第4回 h～i](https://qiita.com/ichi_taro3/items/ee55257338b32c073bad)
[Pythonの組み込み関数69個を制覇する 第5回 l～o](https://qiita.com/ichi_taro3/items/f2cb744a879a084e49af)
[Pythonの組み込み関数69個を制覇する 第6回 p～r](https://qiita.com/ichi_taro3/items/2c2b399b762f5800fe82)

## 関数の使い方
各関数の使い方を記述していきます。詳細な使い方は他の記事に譲るとして、ここでは簡単な使用例を中心に掲載していきます。

#### callable()
一つの引数を取ります。引数のオブジェクトが呼び出し可能オブジェクトかどうかを判定して、True / False を返却します。実用的には、`()`をつけて実行することができるオブジェクトであるかで分類できるでしょう。
呼び出し可能オブジェクトの例としては、関数、クラス、`__call__` が実装されたクラスのインスタンスがあります。

```Python3
>>> # 関数
... sum([1,2])
3
>>> callable(sum)
True
>>> # 自分で定義した関数
... def question():
...     print('To be or Not to be')
...
>>> callable(question)
True
>>> question()
To be or Not to be
>>> # 文字列は呼び出し可能ではない
... callable('PRRRRR')
False
>>> # 数値も呼び出し可能ではない
... callable(2**10)
False
>>> # クラスは呼び出し可能
... class Phone(object):
...     def __call__(self):
...         print('Zzzzzzz')
...
>>> callable(Phone)
True
>>> # __call__が実装されていたら、インスタンスは呼び出し可能
... phone = Phone()
>>> callable(phone)
True
>>> phone()
Zzzzzzz
```

#### chr()
整数を引数にとり、Unicodeのコードポイントがその引数の値である文字を返却します。
引数は0～1,114,111の区間をとり、範囲外の値の場合はValueErrorを起こします。

```Python3
>>> # U+0041
... chr(65)
'A'
>>> # U+0414
... chr(1044)
'Д'
>>> # U+3042
... # 0xを頭につけると16進数で渡せるので扱いやすい
... chr(0x3042)
'あ'
>>> # U+5D50
... chr(0x5D50)
'嵐'
>>> # U+1F31D
... chr(0x1F31D)
'🌝'
>>> # 範囲外はエラー
... chr(1114112)
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError: chr() arg not in range(0x110000)
```

#### classmethod()
クラス定義内で利用され、通常のメソッドをクラスメソッドに変換します。
これにより、メソッドはクラスインスタンスではなく、クラスに対して束縛されます。
通常はデコレータ`@`を使って表現されますが、もちろん使わない書き方も可能です。
クラスメソッドの第一引数にはクラスオブジェクト自身が暗黙に渡されるので、慣例として第一引数は`cls`と書くことが多いようです。

```Python3
>>> class Killer(object):
...     @classmethod
...     def queen(cls):
...         print(cls.__name__, 'Queen')
...
>>> # クラスからメソッドを取り出せる
... Killer.queen()
Killer Queen
>>> # インスタンスからもクラスメソッドは実行可能
... Killer().queen()
Killer Queen
>>> # デコレータの書式を用いない場合
... class Bohemian(object):
...     def rhapsody(cls):
...         print(cls.__name__, 'Rhapsody')
...     rhapsody = classmethod(rhapsody)
...
>>> Bohemian.rhapsody()
Bohemian Rhapsody
>>> Bohemian().rhapsody()
Bohemian Rhapsody
```

#### compile()
引数に渡したソースをコードオブジェクトかASTオブジェクトに変換します。変換結果はexec()で実行したりeval()で評価したりすることができます。
ASTとは抽象構文木(Abstract Syntax Tree)の略で、Pythonインタプリタがプログラムを解析して生成する内部的なデータ構造を指します。
compileはいろいろな引数を受け取るのですが、必須の引数はsource, filename, modeの3つです。sourceは文字列、バイト列、ASTオブジェクトのいずれかを渡すことができます。ASTオブジェクトについては[astモジュール](https://docs.python.jp/3/library/ast.html#module-ast)を利用して生成するのが一般的です。
filenameは、sourceの読み出し元のファイル名を渡しますが、ファイルがない場合は`'<string>'`を使う場合が多いとのことです。modeは、`'exec'`, `'eval'`, `'single'`のいずれかを渡します。
分かりづらいので例を見てください。

```Python3:execモード
>>> source = """
... import math
...
... for i in range(5):
...     print(math.sqrt(i))
... """
>>> code = compile(source, filename='<string>', mode='exec')
>>> exec(code)
0.0
1.0
1.4142135623730951
1.7320508075688772
2.0
```

```Python3:evalモード
>>> # Pythonの式を文字列で渡す
... # 1行の場合はeval
... code = compile('print("Hello")', filename='<string>', mode='eval')
>>> # execでコードオブジェクトを実行できる
... exec(code)
Hello
```

```Python3:singleモード
>>> # singleは「対話モード」
... code = compile('"Hello"', filename='<string>', mode='single')
>>> # 実行時に評価結果が印字される
... eval(code)
'Hello'
```

この他、future文をコントロールするための`flags`、`dont_inherit`引数と、コンパイラによる最適化レベルをコントロールする`optimize`引数があります。

#### complex()
複素数を扱うクラスです。
引数には複素数表現の文字列か、第一引数に実数部、第二引数に虚数部の数値を渡します。

```Python3
>>> # 文字列を渡す
... complex('3+2j')
(3+2j)
>>> # 演算子の周りに空白があるとエラーになる
... complex('2 - 1j')
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError: complex() arg is a malformed string
>>> # 数値を渡すパターン
... complex(2, -1)
(2-1j)
>>> complex(0, 3)
3j
>>> complex(2, 0)
(2+0j)
>>> # 複素数演算
... complex(3, 2) * complex(2, -3)
(12-5j)
>>> complex(1, 2) + complex(2, 1)
(3+3j)

```

#### delattr()
オブジェクトから指定の名前の属性を削除します。
第一引数にオブジェクトを、第二引数に削除したい属性の名前を渡します。

```Python3
>>> class Figure(object):
...     pass
...
>>> # オブジェクトを初期化して属性を設定
... figure = Figure()
>>> figure.shape = 'circle'
>>> figure.shape
'circle'
>>> # 属性を名前を指定して削除
... delattr(figure, 'shape')
>>> # 属性が削除されている
... hasattr(figure, 'shape')
False
>>> figure.shape
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Figure' object has no attribute 'shape'
>>> # 存在しない属性ではAttirbuteError
... delattr(figure, 'shape')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: shape
```

`delattr(figure, 'shape')` は `del figure.shape` と同じ意味になります。

#### dict()
辞書クラスです。引数から新しい辞書オブジェクトを生成して返します。
引数には、キーとバリューのペアがちょうどできるように値を渡してやる必要があります。

```Python3
>>> # 何も渡さない場合は空の辞書
... dict()
{}
>>> # キーワード引数
... dict(yellow='黃', red='赤', green='緑')
{'yellow': '黃', 'red': '赤', 'green': '緑'}
>>> # key-valueペアのタプル
... dict((('one', 1,), ('two', 2,), ('three', 3,),))
{'one': 1, 'two': 2, 'three': 3}
>>> # イテレータ
... data = map(lambda x: (x, x**2,), range(1, 10))
>>> dict(data)
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
>>> # 引数に辞書
... # 新しい辞書オブジェクトが返る
... old = {'shoyu': 'ramen', 'miso': 'ramen', 'tonkotsu': 'ramen'}
>>> new = dict(old)
>>> new
{'shoyu': 'ramen', 'miso': 'ramen', 'tonkotsu': 'ramen'}
>>> id(old) == id(new)
False
```

#### dir()
対象のスコープに存在している名前のリストを返します。
引数を渡さない場合は、実行された場所のローカルスコープの名前一覧が返り値となります。
オブジェクトを引数に渡すと、オブジェクトの持つ有効な属性を返却しようとします。
対象のオブジェクトの実装によって、dir()が返す値はことなってきます。`__dir__()`メソッドが実装されている場合は、優先して`__dir__()`が呼び出されます。
存在しない場合は`__dict__()`属性や型のもつ属性情報を使って名前のリストを作ろうとします。

```Python3
>>> # 引数を渡さないとき
... dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> # importするとスコープ内にモジュール名が入る
... import string
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'string']

>>> # ローカルスコープなので、クラス内ならクラス内の名前を返却する
... class MyClass(object):
...     a = 'あ'
...     i = 'い'
...     u = 'う'
...     e = 'え'
...     o = 'お'
...     mydir = dir()
...     def get_mydir(self):
...         return self.mydir
...
>>> myobj = MyClass()
>>> myobj.get_mydir()
['__module__', '__qualname__', 'a', 'e', 'i', 'o', 'u']
>>> # 対象を渡すとき
... # 持っている属性、メソッド一覧がわかって便利
... dir(str)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
>>> # __dir__()を実装しているとき
... class OriginalDirs(object):
...     def __dir__(self):
...         return ['penguin', 'beaver', 'gopher', 'python']
...
>>> od = OriginalDirs()
>>> dir(od)
['beaver', 'gopher', 'penguin', 'python']
```

#### divmod()
2つの引数をとって、その整数での割り算の結果と余りのペアを返却します。div(ision) + mod(ulo)でdivmodですね。
引数には複素数は使えませんが、整数、浮動小数を使うことができます。

```Python3
>>> divmod(7, 2)
(3, 1)
>>> divmod(3, 3)
(1, 0)
>>> divmod(-5, 3)
(-2, 1)
>>> divmod(0, 3)
(0, 0)
>>> divmod(1, 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
>>> divmod(3.0, 2.0)
(1.0, 1.0)
>>> divmod(4.7, 2.1)
(2.0, 0.5)
>>> divmod(5, 2.7)
(1.0, 2.3)
```

## [第3回](https://qiita.com/ichi_taro3/items/c866b7124415464e8ef1)に続く
[次回](https://qiita.com/ichi_taro3/items/c866b7124415464e8ef1)はenumerate()から。