[2019/12/21] スクリプト言語 Python の文法を、ざっくりと取りまとめ。

■0■ Index

■1■ 特徴
■2■ 複素数、リスト、タプル、辞書、集合
■3■ 論理型
■4■ 演算子
■5■ 実行制御
■6■ 関数
■7■ モジュール、パッケージ
■8■ クラス

■1■ 特徴

・インデントでブロックを表現する。
 Java の "}"(中括弧閉じ)や VB の "End If" の様なブロック閉じ構文がない。
・変数は、すべて、オブジェクトへの参照変数。
・初出の識別子への代入が、変数宣言。
・グローバル変数と、関数スコープのローカル変数。
・ブロックスコープはない。前方参照は不可。
・イミュータブル(同一オブジェクトの値が変えられない)、
 ミュータブル(同一オブジェクトの中身の値が変えられる)。
・id 関数: オブジェクトの一意IDを取得する、
 type 関数: オブジェクトの型を取得する。
 str 関数: オブジェクトの文字列化。オブジェクトの __str__ メソッド呼び出し。
 repr 関数:オブジェクトの文字列化。オブジェクトの __repr__ メソッド呼び出し。
・複素数(complex型)、リスト、タプル、辞書(dictionary型)、集合(set型)の
 文法レベルのサポート。
・タプルのパック、アンパック機能で、複数の値の一括代入や、関数からの複数戻り値の
 取得が可能である。

※注意: スクリプトファイルは UTF-8 である事。

・Python のインストール
 http://www.python.org/ Pythonソフトウェア財団
 ダウンロードしてインストーラを実行。

・Python の開発ツール
 統合開発環境(IDLE)
 インタラクティブシェル
 python コマンド

■2■ 複素数、リスト、タプル、辞書、集合

・複素数(complex): x = 3 + 4j
・リスト(list): lst01 = [1, 2, 3, …, ]
・タプル(tuple): tpl01 = (1, 2, 3, …, ) または、1, 2, 3, …,

イミュータブルなリスト。要素の値は変えられない。
括弧なしで値をカンマ区切りで列挙すると、タプルと見なされる。

※タブルのパックとアンパック
  a, b = x, y

の様に記述すると、x, y からタブルが生成され、a, b にアンパックされる。

・辞書(dictionary): dic01 = {'キー1': 値1, 'キー2': 値2, …, 'キーn': 値n}

※フラットシーケンスとコンテナシーケンス

フラットシーケンス: 同一の組み込み型をそのまま並べた並び
  文字列、array.array型 など
コンテナシーケンス: オブジェクトへの参照の並び
  異なる種類のオブジェクトが並べられる。
  list 型、tuple 型、collections.deque 型 etc.

・集合(set): set01 = {1, 2, 3. …. }

ミュータブル
要素に重複は許されない
等価性の判定において、順序は考慮されない。

■3■ 論理型

・論理型定数: True / False
・整数:0、空リスト、空タプル、空集合、空オブジェクトは False

■4■ 演算子

・算術演算子

+(単項演算子) そのままの値
-(単項演算子) 符号の反転
+ 加算
- 減算
* 乗算
** べき乗
/ 除算(実数)
// 除算(少数部を切り捨てた整数除算)
% 剰余

・ビット演算子

& 論理積
| 論理和
^ 排他的論理和
<< 左シフト
>> 右シフト
~(単項演算子) ビット反転

・論理演算子

not 否定
and 論理積
or 論理和
x if y else z 3項演算子(条件 y が真ならば x、偽ならば y)

・比較演算子

< 小なり
<= 以下
> 大なり
>= 以上
== 等価
!= 不等価

・文字列演算子(リスト、タプルでも同様)

+ 結合
in 探索(あるかないか)
[] インデックス。0および正数ならば先頭から、負数ならば末尾からのインデックス
[開始 : 終了 : ステップ] スライス演算子

・集合演算子

in 要素の有無判定
== 等価
!= 不等価
<= 部分集合
< 真部分集合
>= 超集合
> 真超集合
| union メソッド。和集合を求める。
& intersection メソッド。積集合を求める。
- difference メソッド。差集合
^ synmetric.differecce メソッド。対称差集合
add メソッド。 要素を1つ追加する。
descard メソッド。 要素を指定し削除。要素が含まれてなくてもエラーなし。
remove メソッド。 要素を指定し削除。要素が含まれてないとエラー。
pop メソッド。 要素の無作為な作尾。
clear メソッド。 要素のクリア。

■5■ 実行制御

・if 文

if 条件1:
  処理スイート1
elif 条件2:
  処理スイート2
else:
  処理スイート3

・while 文

while 継続条件:
  処理スイート
else:
  break の際の処理スイート

・for 文

for カウンタ変数 in レンジオブジェクト(range(始め値, 超過値)):
  処理スイート

for カウンタ, データ in enumerate(シーケンス型):
  処理スイート

・continue

ループ先頭に戻る

・break

ループからの脱出

・pass

何も処理のないスイーツに記述

・例外処理文

try:
  処理スイート
excep 例外型 as 例外変数:
  例外処理スイート
else:
  正常終了スイート
finally:
  共通処理スイート

■6■ 関数

・関数定義

def 関数名(仮引数1, 仮引数2, …):
  処理スイート
  return 戻り値

戻り値を指定しなければ、None が返却される。
タブルのパック、アンパックを利用して、複数の戻り値を返却できる。

・文書化文字列とアノテーション

関数の文書化文字列: 関数頭部で、「""" … """」で記述する。

アノテーション: 仮引数と戻り値の型が指定できる。

[例]
def 関数名(引数名 : 型, … ) -> 戻り値注釈(例:None, 戻り値型 etc.)
  """関数の説明"""

help 関数: アノテーションと文書化文字列が画面表示される。
関数.__annotations__: アノテーション文字列取得
関数.__doc__: 文書化文字列取得

※"""の後にスペースを入れると、スペースも文字列の一部と見なされる。

・引数

Python では、"常に" 仮引数は、実引数への参照である。
整数などイミュータブルなオブジェクトでは、関数内での値変更で新しいオブジェクトが生成されるために呼び出し側には影響を与えない。
list などミュータブルなオブジェクトでは、関数内での変更が呼び出し側に反映される。

・引数のデフォルト値

def func01(引数1 = 値1, 引数2 = 値2, …)

デフォルトつき引数の指定は、末尾から連続して指定。
アノテーションと共に指定する場合は、引数 : 型 = デフォルト値

・位置引数とキーワード引数

呼び出しで、
  func01(引数2 = 値, 引数1 = 値)
の様な指定が可能。

・キーワード引数の強制

関数定義で、引数並びの先頭に *, を記述すると、呼び出しは位置引数指定は不可になる(TypeErrorが発生)。

・関数はオブジェクト

変数 = 関数名

関数名に括弧がつかなければ、オブジェクトの代入
括弧がつけば、呼び出し式

・名前空間

関数内での変数定義: ローカルスコープ
関数外での変数定義: グローバルスコープ

局所名前空間で初出の変数名への代入は、(グローバルに同名があっても)変数宣言とみなす。
代入前に global 宣言があれば、グローバル変数を参照する。
代入前に nonlocal 宣言があれば、一つ外側のローカル名前空間を参照する(グローバル空間は見ない)。

参照だけの場合は、外側のローカル名前空間やグローバル変数を参照する。

・ラムダ式

lambda 引数並び : 戻り値

関数オブジェクトを生成する式。
ラムダ式は「式」であり、複合文ではない。
故に、式文の中に入れられる。

[例]
func = lambda x, y: x + y
c = func(a, b)
func = lambda x, y: x - y
c = func(a, b)

■7■ モジュール、パッケージ

別モジュール(ソースファイル)に定義された関数等を利用する

・import文(1)

import モジュール名

XXX = モジュール名.関数名()

・import文(2)

import モジュール名 as 別名

XXX = 別名.関数名()

・import文(3)

from モジュール名 import オブジェクト(関数)名01, オブジェクト(関数)名02, …

XXX = オブジェクト(関数)名()

・import文(4)

from モジュール名 import *

XXX = オブジェクト(関数)名()

モジュール内の全オブジェクトが参照可能になる。

・import文(4)

from モジュール名 import オブジェクト名 as 別名

・モジュール検索

(1) カレントディレクトリ
(2) 環境変数 PYTHONPATH
(3) 標準ライブラリのディレクトリ
(4) サードパーティライブラリのディレクトリ

・完全修飾名(完全限定名)

・パッケージ

モジュールの置かれたディレクトリ
検索パスからの相対パスで表す。
  フォルダ名との境目は "."

__init__.py
  正規パッケージを示す。ディレクトリごとにファイルを配置。
  中は空でも構わない。
  パッケージのimport の際に、初期化処理を行う。

【例01】 モジュールのパスをショートカット
 パッケージ pkg01 に module01.py があり、
  def func01():
 が定義されている場合、呼び出し側で、
  inport pkg01 as p
  
  p.func01() ### 呼び出し(1)
 と記述すると、エラーになる(当然)。

 パッケージ pkg01 に __init__.py を配置して、以下を記述する。
  from pkg01.module01 import *
 すると、呼び出し(1) が成功する。
 モジュールのパスがショートカットできる。

【例02】 関数定義
 __init__.py 内で定義した関数は、呼び出し側ではモジュール名の指定は必要ない。
 パッケージ修飾のみで関数が呼び出せる。

■8■ クラス

・クラス定義

class クラス名:

クラス名はキャメルケース(例:MyClass)
クラス名とモジュール名(ファイルのベースネーム)は、一致しなくて良い。

・インスタンス生成

クラス名による関数呼び出し文

変数 = クラス名()

・属性

暗黙の追加
[例] インスタンス.属性名 = 値

関数も可能
[例] インスタンス.属性名 = 関数名

・コンストラクタ __init__(self, 引数02, 引数03, … )

戻り値は None
第1引数 self を忘れぬように。
呼び方は「ダンダーイニット」

・メソッド

クラス定義の中に、普通に関数定義を記述すればよい。
第1引数 self は忘れずに。

・データの隠蔽とカプセル化

クラスの属性を外部から勝手に変更できないようにする。

メンバー変数名の冒頭に __ をつける。
コンパイルによって名前が変わる。名前難読化。
メンバーは、「_クラス名__変数名」という名前になる。
メソッドにも応用可能。
[注意] 決して、private になる訳ではなく、「アクセスしにくくなる」だけ。

・アクセッサ(setter と setter)

メソッドにデコレータを記述する。

getter: @property
  ゲッター名がプロパティ名になる。
setter: @プロパティ名.setter

メソッド名は、getter と setter で同じで良い。
setter、setter にも、第一引数 self は忘れずに。

呼び出し時には、括弧はいらない。参照や代入をすれば良い。

setter のないプロパティは、変更不可(難読化により困難)。

・デリータ(deleter)

メンバーの削除をカスタマイズ。

@プロパティ名.deleter
def プロパティ名(self) -> None:
  処理

プロパティに del 演算子が作用された時に呼び出される。

・文字列化

__str__ メソッド
  Java の toString メソッドに相当か???
  第1引数 self は忘れずに!
  str 関数の戻り値になる。

__repr__ メソッド
  公式な文字列。
  eval 関数で、文字列から元のインスタンスが複製可能。
  インスタンスの等価性チェックにも使われる。

・クラス変数とクラスメソッド

クラス変数
  クラス定義の中、メソッドの外で定義(値の代入)した変数
  参照する時は、「クラス名.変数名」で指定。
  内部で参照する場合も、クラス名での修飾は必須。

クラスメソッド
  @classmethod デコレータで修飾。
  第1引数 cls は必須。

静的メソッド
  @staticmethod デコレータで修飾。
  第1引数 cls は不要。

・継承

クラス宣言
  class サブクラス名(スーパークラス名):

・共通の上位クラス object

・多重継承をサポート

クラス宣言
  class サブクラス名(スーパークラス名01, スーパークラス名02):