マニュアル: Python

投稿日: 更新日:

基本構文

内包表記

条件式、内包表記の覚え方

まだ習いたてなのでこれで合っているかどうかは分からん。

  • 条件式: x if C else y
  • 内包表記(リスト): [x**2 for x in range(10)]
  • 内包表記(辞書): {x: x**2 for x in (2, 4, 6)}

以下のような特徴があるかなと。

条件式は「一番知りたい」のがtrueのときの値でこれが左に来ている。 Rubyなら if C then x else y end となるが、 一番知りたいxが左に来て、then, endを削除するとx if C else y になる。

内包表記(リスト)は「一番知りたい」のが各リストの計算式で、これが左に来ている。 残りはループの条件で for x in range(10) 。これはbashやJavaScriptなどで使われる構文なので違和感はない。 最後にリストなので [] で囲めばOK。

内包表記(辞書)は値がリストの構文と同じで、あとは辞書らしく x: でキーを指定して、全体を {} で囲む。

組み込み関数

  • dir: そのオブジェクトなどで定義されている名前、属性のリストを返す。
    • Rubyでいう methods みたいなもの。
  • id: オブジェクトの識別子を返す。
  • repr: オブジェクトの文字列表現(evalして元に戻すことを想定)
    • Rubyでいう inspect みたいなもの。
  • round: round(num, i) で、numの小数部をi桁に丸める。
    • numが0の場合は round(3.14, 0) → 3.0のようになる
  • zip: それぞれの要素の最初から順番にとってくるiteratorを作成する。
    • 分かりにくいので例:
      • 入力: print(list(zip((1, 2, 3), (4, 5, 6), (7, 8, 9))))
      • 結果: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

組み込み型

文字列型

Pythonでの文字列の特徴

  • シングルクォート(')とダブルクォート(")で機能的な違いはない
  • 文字列を並べると結合される
  • 文字型(char)は存在しない
    • ordで「文字 → Unicodeコードポイント」に変換可能
    • chrで「Unicodeコードポイント → 文字」に変換可能
  • フォーマット文字列
  • 生文字列: r'...' の文字列。
  • str.replace: 文字列の置換
    • 引数はold, new, count(オプション)

シーケンス型(リスト、タプル、range)

また、文字列もシーケンス型の一つとなっている。

リストとタプルとの違いは、リストがmutableで、タプルがimmutableであること。

主なメソッド。

  • 末尾に追加: list.append(x)
  • 一致する最初の要素を削除: list.remove(x)
  • 末尾から削除: list.pop()
    • list.pop(i) のように引数指定でその位置から削除

アンパック

1つカッコを取る。例えば以下のようになる。

foo = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(foo)  # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(*foo)  # [1, 2, 3] [4, 5, 6] [7, 8, 9]

スライス

s[start:stop:step] のような形式を使うと、シーケンスの一部分だけアクセスできる。 これをスライスと言う。スライスの終端は含まないため、 a[:i] + a[i:] = a が成り立つ。

a = [1, 2, 3, 4, 5]
a[1:3] # =>[2, 3]
a[1:]  # =>[2, 3, 4, 5]
a[:1]  # => [1]
a[::2] # => [1, 3, 5]
a[:2] + a[2:] # => [1, 2, 3, 4, 5]

代入もできる。

a = [1, 2, 3, 4, 5]
a[1:3] = [6]
a # => [1, 6, 4, 5]

当然immutableなtupleやstrには代入できない。

a = (1, 2, 3, 4, 5)
a[1:3] = [6] # => TypeError: 'tuple' object does not support item assignment

s = "12345"
s[1:3] = "6" # => TypeError: 'str' object does not support item assignment

辞書型

Pythonでの特徴

  • {'jack': 4098, 'sape': 4139}のように書く(JSONっぽい)
  • キーはほぼ任意の型が使える
  • 値の取得: d[key]
  • 同様に ** でアンパックできる
  • list(d): キーのリスト(挿入順)
  • sorted(d): キーのリスト(ソート済み)
  • key in d: キーが辞書に含まれているか
  • key not in d: キーが辞書に含まれていないか
  • for key, value in dict.items(): キーと値をループ
  • 作成方法はリンク先参照

例外処理

ポイントは次の通り。

  • try, except, else(オプション), finally(オプション)の4つの節からなる。
  • except (RuntimeError, TypeError, NameError): のようにまとめて書くことができる。
  • 例外を変数に割り当てたいときは、 except OSError as err: のように書く。
  • raiseで例外を投げる

例外クラス

  • ルート: BaseException(JavaでのThrowable)
  • 新しい例外の継承元: Exception(JavaでのException)
    • Exceptionとなっているが、例外クラス名は通常 Error で終わる。

モジュール

クラス

class の直下で変数定義をすると、クラス変数になる。

ちなみにDjangoでクラス変数を使っても問題ないのは、Djangoが頑張って退避している模様。

特殊メソッド

演算子オーバロードなどで使われる。

  • __init__: インスタンスの初期化
  • __repr__: オブジェクトを表す「公式」文字列
    • Rubyで言えばinspectかなぁ・・・
  • __format__: フォーマット文字列
  • __lt__, __le__, __eq__, __ne__, __gt__, __ge__, : 比較メソッド
    • __ne__ が未実装のときは __eq__ を呼び出して反転する
    • それ以外は個々に実装する必要があるが、面倒なときは functools.total_orderingで簡略可能。
  • __hash__: ハッシュ値
  • __bool__: ブール値
  • withで使われるもの
    • __enter__
    • __exit__

ロギング

logging自体でも使えますが、以下のようにloggerを使うのが良さげ。

logger = logging.getLogger(__name__)

コーディング規約(PEP 8)

気になったところから少しずつまとめていきます。

  • インデント: スペース4つ。タブは禁止(Python 3)
  • 1行79文字以下
    • 標準ライブラリでは必須だが、実際には守られない(プロジェクトでこの条件を外す)ことが多い模様。
  • 関数やクラスの定義の前には改行が2つ必要。

デコレータ

@ + デコレータ名 で修飾します。

関数をラップしていろいろ処理を加えたりするものです。 記号はJavaのアノテーションみたいですが、どちらかといえばAOP(アスペクト指向プログラミング)に近いですね。

型ヒント

Python 3.5から採用されたもの。

だいたいこんな感じ。

  • 引数は name: str のような形式
  • 関数、メソッドは def geeting(name: str) -> str のような形式
  • # type: int のようにコメントをつける方法もある。

typing モジュールで型ヒントをサポートするサポートが追加されている。

  • List: listに対応するもの(JavaではArrayListに相当?)
  • Sequence: JavaではListに相当?
  • Iterable

モック方法

  • クラスをモックする場合: mock.patch(クラス名の文字列, ...)
  • メソッドをモックする場合: mock.patch.object(クラスオブジェクト, メソッド名の文字列, ...)

venv

仮想環境を提供するもの。 Python自体に組み込まれているため、Pythonのバージョンは管理できない。

# 環境作成。最後のvenvは環境名
python -m venv venv

# アクティベート
. venv/bin/activate

# アクティベート状態から抜ける
deactivate