静岡理工科大学 菅沼ホーム Python と C/C++ 目次

Python 概説

      1. Python の実行
        1. 対話モード
        2. ファイルの利用
      2. プログラム構造
        1. 行構造
        2. コメント
      3. 基本単位
        1. リテラル
          1. 文字列およびバイト列リテラル
          2. エスケープシーケンス
          3. 数値リテラル
        2. 変数
        3. 識別子(名前)
        4. 演算子と式
          1. 比較と論理演算
          2. 数値演算
          3. ビット単位の演算
      4. 複合データ
        1. シーケンス型
          1. 要素の参照(添え字とスライス)
          2. シーケンス型に共通の演算
          3. 変更不可能なシーケンス
            1. 文字列型
            2. タプル型( tuple )
            3. bytes 型
          4. 変更可能なシーケンス
            1. 変更可能シーケンスに固有の演算
            2. リスト型( list )
            3. NumPy における配列
            4. range 型
            5. bytearray 型
        2. 集合型
        3. マッピング型(辞書型)
      5. 入出力と文
        1. 入出力
          1. 標準入出力
          2. ファイル入出力
        2. 単純文
          1. 代入文
          2. del 文
          3. import 文
          4. pass 文
        3. 複合文
          1. if 文
          2. while 文
          3. for 文
          4. with 文
          5. try 文
      6. 関数
        1. 関数の定義
          1. 引数とデフォルト
          2. 引数の型(リスト)
          3. 引数の型(関数)
          4. 再帰呼び出し
          5. 可変個の引数
          6. ローカル変数とグローバル変数
        2. ジェネレータ関数
      7. クラス
        1. クラスの定義
        2. 初期化
        3. 継承
        4. インスタントメソッド,クラスメソッド,スタティックメソッド
      8. 変数の有効範囲(スコープ)
  1. Python の実行

    1. 対話モード

        Window のコマンドプロンプトを起動し,

      > Python

      と入力すると,Python のインタプリータが起動し,「 >>> 」というコマンドプロンプトが表示されるはずです(もちろん,この前に,Python をインストールし,適切な箇所に PATH を設定しておく必要があります).ただし,Python 3.3 とそれ以降のシステムワイドなインストールでは,ランチャが PATH に追加され,2 種類の Pythonがインストールされていても,

      > py -2 # Python 2.* の実行
      > py -3 # Python 3.* の実行

      のいずれかを入力すれば,希望する Python インタプリータを起動することができます.以後の例においても同様ですが,上の例における # から行末まではコメントです.なお,インタプリータを終了させるには,ctrl-Z,または,quit() を入力します.

        以下の例に示すように,プロンプト「 >>> 」が表示されている状態で,式や関数を入力すれば,その結果が出力されます.なお,以後の例においても同様ですが,行番号は,説明のために付加してあります.

      01	>>> print(2 + 3)
      02	5
      03	>>> 3 + 4
      04	7
      05	>>> a = 10
      06	>>> if a == 10:
      07	...     print(a)
      08	...
      09	10
      10	>>> 'abc'
      11	'abc'
      				
      01 行目

        print() はオブジェクトを表示するための組み込み関数です.表示されるオブジェクトは,組み込み関数 str() が行うように文字列に変換されます.Python においては,数値,数値の集まり,など,ほとんどのものをオブジェクトと呼びます.ここでは,演算した結果を表します.

      06 行目~ 08 行目

        一つの命令が複数行にわたる場合,2 行目以降に対してはプロンプト「 ... 」が表示されます.複数行にわたる命令を終了させるためには,プロンプト「 ... 」に対して改行だけを入力します( 08 行目).Python においては,字下げ自体が構造を決定する要素であるため,必ず字下げする必要があります( 07 行目).

        また,以下に示すように,対話モードに入ること無しに,Python のコマンドを実行することも可能です.結果は,Window のコマンドプロンプト上に出力されます.
      py -3 -c print(2+3)   # 一般形: python -c command [arg] ... 
      				

    2. ファイルの利用

        複雑な処理を行いたい場合,対話モードを利用して一連のコマンドを順に入力していくことは大変な作業になります.そこで,一連のコマンド(スクリプト)をファイル,例えば cal1.py (一般的に,ファイル名は「~.py」)に,
      # -*- coding: UTF-8 -*-
      a = 10
      b = 20
      print(a + b)
      				
      のような形で保存し,Window のコマンドプロンプト上において,
      py -3 cal1.py   # 一般形: python ファイル名 [arg] ... 
      				
      と入力することによって,結果を得ることができます.なお,ファイル内容の 1 行目は,文字コードを表しています.

        モジュールも,上に示したファイルと同様,Python の定義や文が入ったファイルです.大きなプログラムの一部や,他のプログラムにおいても使用可能な汎用的な処理部分を記述するために使用されます.例えば,以下に示すモジュール cal2.py は,加算または減算を実行し出力するためのものです.なお,def で始まる部分は,関数を表しています.
      # -*- coding: UTF-8 -*-
      
      def add(a, b):
      	c = a + b
      	print(c)
      
      def sub(a, b):
      	c = a - b
      	print(c)
      				
      このモジュールを使用することによって,例えば,以下に示すような処理を実行できます.
      >>> import cal2
      >>> cal2.add(2,3)
      5
      >>> cal2.sub(2,3)
      -1
      				
        「cal2.add(2,3)」の「cal2.」の部分を記述したくない場合は,上の 1 行目の代わりに,
      >>> from cal2 import add
      				
      を入力してやれば,「add(2,3)」の記述で正しく動作します.また,
      >>> from cal2 import *
      				
      という記述を利用すれば,モジュールで定義されている全ての名前(関数内で定義されているローカルな変数名は除く)を import できます.この例の場合は,関数 sub に対しても,「sub(2,3)」の記述で正しく動作するようになります.

        場合によっては,モジュールまたはその一部を,Window のコマンドプロンプト上から実行したい場合があります.例えば,上の例において,関数 add を実行したい場合について考えてみます.Window のコマンドプロンプト上から
      py -3 cal2.py 2 3
      				
      と入力しても何も出力されません.しかし,cal2.py の最後に,
      if __name__ == "__main__":
      	import sys
      	add(int(sys.argv[1]), int(sys.argv[2]))
      				
      の 3 行を追加すると,
      py -3 cal2.py 2 3
      py -3 -m cal2 2 3
      				
      のいずれの方法によっても,結果が正しく表示されるようになります.なお,__name__ は,モジュール名が記憶されているグローバル変数です.
  2. プログラム構造

    1. 行構造

        自然言語と同様,一つの文の開始や終了位置に特別な制限がなく,フリーフォーマットで記述できるプログラミング言語が多い中で,Python のプログラムは行単位(行頭から改行まで)で処理されます.ただし,一つの文を 1 行で記述できない場合は,以下に示すように,バックスラッシュ文字「 \ 」を使って継続させることが可能です.また,\ で継続する行(下に示す文の 1,2 行目)の後ろには「 # 」記号を使用してコメントを記述することができません.
      a = abc + efg * xxx \
          + aaa - bbb / ccc \
          + yyy / 30 + hhh   # ~ に関する計算
      				
        なお,以下に示すように,丸括弧 ( ),角括弧 [ ],および,波括弧 { } 内の式は,バックスラッシュを使わずに複数行を使用して記述することが可能です.このときは,各行ごとにコメントを記述することができます.
      aaa = [1, 2, 3,   # ~
             4, 5, 6,   # ~
             7, 8, 9]   # ~ 
      				
        if 文while 文など,実行順序を制御するための文が Python にも存在します.詳細については後ほど述べますが,ここでは,行単位の入力方法について説明します.例えば,if 文の場合,以下に示すように記述されます.この文は,条件が真であれば 02,03 行目を実行し,偽であれば 05,06 行目を実行することを意味しています.この例に示すように,Python の場合は,半角スペースまたは Tab を使用して字下げを行うことによって,その制御範囲を記述することになります.
      01	if 条件 :
      02		a = 10
      03		b = 20
      04	else :
      05		c = 30
      06		d = 40
      				

    2. コメント

        以下に示すように, # から改行まではコメントとみなされます.
      a = 10   # 変数 a に 10 を代入 
      				
        また,以下に示すように,Python スクリプト中の 1 行目か 2 行目にあるコメントが正規表現 coding[=:]\s*([-\w.]+) にマッチする場合,コメントはエンコード宣言(プログラムを記述する文字コードの宣言)として処理されます.
      # -*- coding: UTF-8 -*-
      				
        Python には,C/C++ における /* と */ のように,複数行にわたるコメントを記述する記号は存在しません.しかし,Python では,代入などの演算を行わず,単に文字列だけを記述した場合,その文字列に対する処理は行われません.そこで,3 連引用符(引用符を 3 つ続ける) ''',または, """ を使用した複数行に亘る文字列を利用することにより,以下に示すように,複数行にわたるコメント(的な文字列)を記述することが可能です.
      """
         コメント・・・
         コメント・・・
      """
      				
  3. 基本単位

    1. リテラル

      1. 文字列およびバイト列リテラル

          文字列リテラルおよびバイト列リテラルbytes 型リテラル)は,対応する一重引用符「 ' 」,または,二重引用符「 " 」で囲まれます.Python においては,二つの引用符は同じ意味になります.文字列は,+ 演算子を使用して連結させることができ,* 演算子で反復させることができます.また,文字列リテラルをスペースで区切って並べると,それらは自動的に連結されます.なお,バイト列リテラルに対しては,常に b や B が接頭し,ASCII 文字のみを含むことができます.
        >>> 2 * "abc" + "efg" + "hij"
        'abcabcefghij'
        >>> 2 * "abc" "efg" "hij"
        'abcefghijabcefghij'
        >>> b"abc"
        b'abc'
        >>> b"文字列"   # エラー( ASCII 文字だけ可能)
        					
          複数行に亘る文字列は,対応する 3 連の引用符 ''',または,""" によって可能です.
        >>> """
        ... abc
        ... def
        ... ghi
        ... """
        '\nabc\ndef\nghi\n'
        					

      2. エスケープシーケンス
        	\newline  行末に \ を記述するとその行の改行が無視される
        	\\        バックスラッシュ(円記号)
        	\'        一重引用符(シングル クォーテーション)
        	\"        二重引用符(ダブル クォーテーション)
        	\a        ベル              
        	\b        バック スペース   
        	\f        改ページ          
        	\n        行送り              
        	\r        復帰              
        	\t        水平タブ          
        	\v        垂直タブ
        	\ooo      8進表記による ASCII 文字
        	\xhh      16進表記による ASCII 文字
        					
          以下に示すエスケープシーケンスは,文字列に対してだけ有効です.
        	\N{name}    Unicode データベース中で name という名前の文字
        	\uxxxx      16-bit の十六進値 xxxx を持つ文字
        	\Uxxxxxxxx  32-bit の十六進値 xxxxxxxx を持つ文字
        					

      3. 数値リテラル

        • 整数リテラル: 10 進数,8 進数 0ohhhh,16 進数 0xhhhh,または,2 進数 0bhhhh ( o,x,b は大文字でも良い).なお,値がメモリ上に収まるかどうかという問題を除けば,整数リテラルには長さの制限がありません.真偽値も整数リテラルの一種であり,FalseTrue の値をとります.真偽値を表すブール型は整数型の派生型であり,ほとんどの状況でそれぞれ 0 と 1 のように振る舞います.
          >>> 10 + True
          11
          						
        • 浮動小数点数リテラル: 取りうる値の範囲は実装に依存

        • 虚数リテラル: aj ( aJ )のように表現し,実数部が 0.0 の複素数を表します.実数部がゼロでない複素数を生成するには,( 3 + 4j ) のように虚数リテラルに浮動小数点数を加算するか,または,組み込み関数 complex() を使用します.
          >>> 3.14j   # 3.14J でも良い
          3.14j
          >>> 2.5 + 3.14j
          (2.5+3.14j)
          >>> complex(2.5, 3.14)
          (2.5+3.14j)
          >>> complex(2.5, 3.14).real   # 実数部の参照(参照だけ可能)
          2.5
          >>> complex(2.5, 3.14).imag   # 虚数部の参照(参照だけ可能)
          3.14
          						

    2. 変数

        Python においては,代入または入力したデータによって,その変数の型が決まります.ただし,Python の場合は,変数が示す場所(アドレス)にデータ自身が記憶されているわけではなく,変数はデータ(オブジェクト)が記憶されている場所への参照(場所のアドレス)を表しています.従って,変数の型という表現は不適切ですが,今後,混乱が生じない範囲で使用していきます.このように,Python における変数は,C/C++ におけるポインタと似ています.

    3. 識別子(名前)

        識別子とは,変数,関数,クラス等の名前に相当します.ASCII 範囲では,アルファベット,下線 _,及び,数字(先頭の文字を除く)を利用できます.ただし,下線 _ から始まる識別子には,以下に示すように,特別な意味がある場合があります( * の部分は,任意の文字列).

      _*  from module import * で import されません.また,対話インタプリタでは,直前に行われた評価の結果を記憶するために識別子「 _ 」が使われます.

      __*__  システムで定義された (system-defined) 名前です.

      __*  そのクラスのプライベートな名前とみなされ,コードが生成される前により長い形式に変換されます.

        また,以下に示す識別子は,Python 言語におけるキーワード (keyword) として使われ,通常の識別子として使うことはできません.
          False      class      finally    is         return
          None       continue   for        lambda     try
          True       def        from       nonlocal   while
          and        del        global     not        with
          as         elif       if         or         yield
          assert     else       import     pass
          break      except     in         raise
      				

    4. 演算子と式

      1. 比較と論理演算
            <  : より小さい  a < b
            >  : より大きい  a > b
            <= : 以下  a <= b
            >= : 以上  a >= b
            == : 等しい      a == b
            != : 等しくない  a != b
            is     : 同じオブジェクト  a is b
            is not : 同じオブジェクトではない  a is not b
        					
        		# 整数の場合,文字列の場合も同じ
        01	>>> a = 10
        02	>>> b = 10
        03	>>> a == b, a is b
        04	(True, True)
        05	>>> b = a
        06	>>> a == b, a is b
        07	(True, True)
        08	>>> b = 20
        09	>>> a == b, a is b
        10	(False, False)
        11	>>> a, b
        12	(10, 20)
        		# 浮動小数点数の場合,虚数(複素数)の場合も同じ
        13	>>> c = 1.2
        14	>>> d = 1.2
        15	>>> c == d, c is d
        16	(True, False)
        17	>>> d = c
        18	>>> c == d, c is d
        19	(True, True)
        20	>>> d = 1.3
        21	>>> c == d, c is d
        22	(False, False)
        23	>>> c, d
        24	(1.2, 1.3)
        					
          代入とは,= 記号の右辺で得られた結果を左辺で指定した変数が示す領域に記憶することです.01,02 行目においては,整数リテラル 10 が変数 a,b が示す領域に記憶されます.03,04 行目を見ると,値の比較においても,オブジェクトの比較においても,両者は等しくなっています.このことは,整数リテラル 10 が記憶領域のいずれかの場所にただ一つだけ記憶されており,変数 a,b はその(オブジェクトの)アドレスを指していることになります.つまり,変数 a,b は,C/C++ におけるポインタと非常に似ています(下の左図).従って,変数 b の値を変数 a に代入しても( 05 行目),その結果は変わりません.また,変数 b の値を変更すると( 08 行目),変数 b は異なる整数リテラル 20 を指すことになり,両者はいずれの比較においても異なってきます( 09,10 行目,下の右図).当然,変数 b の値を変更しても,変数 a の値は変化しません( 11,12 行目).下の左図の状態において,リテラル 10 を直接修正すれば,変数 a と b の値が同時に変化するはずですが,それを実行する演算子が存在しない,リテラルの値を修正できない,などの点から,Python では不可能です.

          しかし,浮動小数点の場合は多少異なってきます.変数 c や d がポインタであることに違いはないのですが,13 行目~ 16 行目から明らかなように,全く同じ値のリテラルであっても,異なる場所に記憶されている(異なるオブジェクトである)ことを意味します(下の左図).ただし,変数 c を変数 d に代入すれば,整数の場合と同じような状態になります( 17 行目~ 19 行目,下の右図).

          以上述べた演算子を利用して,以下に示すような論理演算が可能です.
            式1 or 式2  : 論理和(式1 または 式2 が True であれば True,そうでなければ False)
            式1 and 式2 : 論理積(式1 及び 式2 が True であれば True,そうでなければ False)
            not 式      : 否定(式 が False であれば True,そうでなければ False)
        					
          C/C++ とは異なり,例えば,「 x < y < z 」が「 x < y and y < z 」とほぼ等価になることに注意してください.
        >>> (3 < 2) and (2 < 5)
        False
        >>> 3 < 2 < 5
        False
        >>> 3 < 4 < 5
        True
        					

      2. 数値演算

          Python には以下に示すような数値演算を行うための演算子が存在します.なお,C/C++ と同様,代入と加算を同時に行う演算子 += など,-=,*=,・・・ も可能です.ただし,C/C++ とは異なり,インクリメント演算子 ++,デクリメント演算子 --条件演算子 = ? : が存在しないことに注意してください.
            +  : 加算(複素数に対しても可能),結合  x + y
            -  : 減算(複素数に対しても可能),符号の変更  x - y, -x
            *  : 乗算(複素数に対しても可能),繰り返し  x * y, *x
            ** : べき乗(複素数に対しても可能,C/C++ には存在しない)  x ** y
            /  : 除算(結果は浮動小数点数,複素数に対しても可能)  x / y
            // : 除算(小数点以下を切り捨て)  x // y
            %  : 余り(浮動小数点数に対しても可能)  x % y
        					
        以上の演算子を使用した演算と共に,複素数に対しては,以下に示すような処理が可能です.
        >>> a = complex(1, 2)
        >>> a
        (1+2j)
        >>> a.conjugate()   # 共役複素数
        (1-2j)
        >>> a.real   # 虚部は a.imag
        1.0
        >>> a.real = 5   // エラー,参照だけが可能
        					

      3. ビット単位の演算
            << : 左にビットシフト  a << 3
            >> : 右にビットシフト  a >> 3
            &  : ビットごとの論理積  x & y
            |  : ビットごとの論理和  x | y
            ^  : ビットごとの排他的論理和  x ^ y
            ~1 の補数( 0 と 1 の逆転)  ~x
        					
  4. 複合データ

    1. シーケンス型

      1. 要素の参照(添え字とスライス)

          シーケンス型のデータを参照する基本的な方法は,添え字です.ただし,Python においては,負の添え字も使用することができます.ここでは,文字列,
        test = "Suganuma"
        					
        を例として,説明していきます.正の添え字を使用する場合,先頭の文字に対応する添え字は 0,最後の文字に対応する添え字が (n-1) (文字数が n の場合)になります.また,負の添え字を使用する場合は,最後の文字に対応する添え字が -1,先頭の文字に対応する添え字が -n (文字数が n の場合)になります.上に示した文字列に対して,その添え字は,
        +---+---+---+---+---+---+---+---+
        | S | u | g | a | n | u | m | a |
        +---+---+---+---+---+---+---+---+
          0   1   2   3   4   5   6   7
         -8  -7  -6  -5  -4  -3  -2  -1
        					
        となり,
        >>> test = "Suganuma"
        >>> test[0]
        'S'
        >>> test[-2]
        'm'
        					
        のような結果が得られます.

          Python においては,スライス( slice )という表現を使用し,部分文字列を指定することが可能です.スライスは,
        [m1:m2[:m3]]
        					
        のように記述され,添え字 m が m1 <= m < m2 である部分文字列を指定することができます.開始インデックス m1 を省略すると 0,終了インデックスを省略すると文字列の長さと見なされます.なお,m3 を入力すると,m1 から m2 までの m3 個ごとの要素という意味になります.この結果,上に示した例に対しては,以下に示すような結果が得られます.
        >>> test = "Suganuma"
        >>> test[0:4]
        'Suga'
        >>> test[:4]
        'Suga'
        >>> test[4:]
        'numa'
        >>> test[4:-1]
        'num'
        >>> test[0:8:2]
        'Sgnm'
        					

      2. シーケンス型に共通の演算

          以下に示す演算は,ほとんどの変更不可能及び変更可能なシーケンス型でサポートされています.同じ型のシーケンス同士に対しては,比較もサポートしています.等しいとされるためには,すべての要素が等しく,両シーケンスの型も長さも等しくなければなりません.

        • + : 結合
        • * : 繰り返し
        • count : 出現回数
        • in : 包含関係
        • index : 検索
        • len : 長さ(組み込み関数)
        • max : 最大(組み込み関数)
        • min : 最小(組み込み関数)
        • not in : 包含関係でない

      3. 変更不可能なシーケンス

        1. 文字列型
            文字列str オブジェクトであり,一重引用符「 ' 」または二重引用符「 " 」で囲み,結果はどちらも同じ文字列になります.また,一重引用符または二重引用符を 3 つ続ける(「 ''' 」または「 """ 」)ことによって,複数行にわたる文字列も表現できます.文字列リテラルに関しては,「文字列およびバイト列リテラル」も参考にしてください.文字列を修正したい場合は,修正した内容を持つ新しい文字列を生成することによって対応可能です.文字列に対しては,先に述べたシーケンス型に共通の演算全てに加え,以下に述べるメソッドを使用することができます.

          • capitalize : 最初の文字だけを大文字に変換
          • center : 中央揃い
          • count : 出現回数
          • endswith : 指定した文字で終わっているか?
          • expandtabs : タブを半角スペースに変換
          • find : 文字列の探索
          • format : 書式化
          • index : 文字列の探索
          • isalnum : 英数字か?
          • isalpha : 英字か?
          • isdecimal : 十進数字か?
          • isdigit : 数字か?
          • isidentifier : 識別子として有効か?
          • islower : 小文字か?
          • isnumeric : 数を表す文字か?
          • isprintable : 印刷可能か?
          • isspace : スペースか?
          • istitle : タイトルケースか?
          • isupper : 大文字か?
          • join : 文字列の結合
          • ljust : 左揃え
          • lower : 小文字に変換
          • lstrip : 先頭文字の削除
          • partition : 文字列を前から見た最初の区切り文字で 3 分割
          • replace : 文字列の置換
          • rfind : 文字列の後方からの探索
          • rindex : 文字列の後方からの探索
          • rjust : 右揃え
          • rpartition : 文字列を後ろから見た最初の区切り文字で 3 分割
          • rsplit : 区切り文字で文字列を分割
          • rstrip : 末尾の文字の削除
          • split : 区切り文字で文字列を分割
          • splitlines : 文字列を改行で分割
          • startswith : 指定した文字で始まっているか?
          • strip : 先頭及び末尾の文字を削除
          • swapcase : 大文字と小文字の変換
          • title : タイトルケースに変換
          • upper : 大文字に変換
          • zfill : 0 で左詰

        2. タプル型( tuple )

            タプルtuple )の要素は任意の Python オブジェクトです.タプルは,以下に示すような方法で生成することができます.なお,タプルを生成するのはカンマであり,問題がなければ,丸括弧 () を省略してかまいません.

          • 空のタプル  (),または,組み込み関数 tuple() の使用
            >>> ()
            ()
            >>> tuple()
            ()
            							

          • 単要素のタプル  (a,),または,組み込み関数 tuple(単要素の iterable) の使用.iterableイテラブル)とは,構成要素を一度に一つずつ返すことができるオブジェクトである.下に示す 3 番目の例では,リストを使用している.
            >>> ("abc",)
            ('abc',)
            >>> "abc",
            ('abc',)
            >>> tuple(["abc"])
            ('abc',)
            							

          • 一般的なタプル  (a, b, ・・・),または,組み込み関数 tuple(iterable) の使用.tuple() は,iterable の項目と同じ項目で同じ順のタプルを構築する.最後の 3 行のように,タプルの要素をタプルとして,2 次元配列に対応したタプルを生成することも可能である.
            >>> ("abc", 10, "xxx")
            ('abc', 10, 'xxx')
            >>> "abc",10,"xxx",
            ('abc', 10, 'xxx')
            >>> tuple(["abc", 10, complex(1,3)])
            ('abc', 10, (1+3j))
            >>> tuple("abc")
            ('a', 'b', 'c')
            >>> a = ((1, 2, 3), (10, 20, 30))
            >>> a[0][1]
            2
            							

        3. bytes 型

            bytes オブジェクトの要素は,8-bit,1 バイトであり,0 <= x < 256 の範囲の整数で表現されます.以下に示すような方法で生成することができます.

          • リテラルの利用  文字列リテラルと同様の方法で生成可能.ただし,文字列の前に b を付加する必要がある.
            >>> b"abc"
            b'abc'
            							

          • 組み込み関数 bytes() を使用し,指定された長さの 0 で埋められた bytes オブジェクトを生成
            >>> bytes(5)
            b'\x00\x00\x00\x00\x00'
            							

          • 組み込み関数 bytes() と整数を要素とする iterable の利用.iterableイテラブル)とは,構成要素を一度に一つずつ返すことができるオブジェクトである.下の例では,rangeリストを使用している.
            >>> bytes(range(5))
            b'\x00\x01\x02\x03\x04'
            >>> bytes([1, 2, 3, 4, 5])
            b'\x01\x02\x03\x04\x05'
            							

            bytes に対しては,先に述べたシーケンス型に共通の演算全てに加え,以下に述べるメソッドを使用することができます.

          • capitalize : 最初の文字だけを大文字に変換
          • center : 中央揃い
          • count : 出現回数
          • decode : bytes を文字列に変換
          • endswith : 指定した文字で終わっているか?
          • expandtabs : タブを半角スペースに変換
          • find : 文字列の探索
          • fromhex : 16 進表記文字列を bytes に変換
          • hex : bytes を 16 進表記に変換
          • index : 文字列の探索
          • isalnum : 英数字か?
          • isalpha : 英字か?
          • isdigit : 数字か?
          • islower : 小文字か?
          • isspace : スペースか?
          • istitle : タイトルケースか?
          • isupper : 大文字か?
          • join : 文字列の結合
          • ljust : 左揃え
          • lower : 小文字に変換
          • lstrip : 先頭文字の削除
          • partition : 文字列を前から見た最初の区切り文字で 3 分割
          • replace : 文字列の置換
          • rfind : 文字列の後方からの探索
          • rindex : 文字列の後方からの探索
          • rjust : 右揃え
          • rpartition : 文字列を後ろから見た最初の区切り文字で 3 分割
          • rsplit : 区切り文字で文字列を分割
          • rstrip : 末尾の文字の削除
          • split : 区切り文字で文字列を分割
          • splitlines : 文字列を改行で分割
          • startswith : 指定した文字で始まっているか?
          • strip : 先頭及び末尾の文字を削除
          • swapcase : 大文字と小文字の変換
          • title : タイトルケースに変換
          • upper : 大文字に変換
          • zfill : 0 で左詰

      4. 変更可能なシーケンス

        1. 変更可能シーケンスに固有の演算

            以下に示す演算は,ほとんどの変更可能なシーケンスで使用可能です.ここで,s は変更可能なシーケンス型のオブジェクト,t は任意のイテラブルオブジェクト,x は s に課せられた型と値の条件を満たす任意のオブジェクトです.ここで,iterableイテラブル)とは,リストタプルrange など,構成要素を一度に一つずつ返すことができるオブジェクトです.

          • s *= n : n 回反復
          • s[i] = x : 代入
          • s[i:j] = t : 代入
          • s[i:j:k] = t : 代入
          • del s[i:j] : 削除
          • del s[i:j:k] : 削除
          • append : 追加
          • clear : 全削除
          • copy : 浅いコピー
          • extend : 追加
          • insert : 挿入
          • pop : 取り出して削除
          • remove : 削除
          • reverse : 順序の逆転

        2. リスト型( list )

            リストlist )は変更可能なシーケンスであり,一般的に同種の項目の集まりを格納するために使われます.リストの生成には,以下に示すように,いくつかの方法があります.

          • [],または,組み込み関数 list() の使用  空のリスト
            >>> []
            []
            >>> list()
            []
            							

          • 角括弧とカンマの使用
            >>> [1, 2, 3]
            [1, 2, 3]
            >>> a = [1, 2, 3]
            >>> a[0]
            1
            >>> b = [[1, 2, 3], [4, 5, 6]]
            >>> b[1][0]
            4
            							

          • list(iterable) の使用
            >>> list("abcd")
            ['a', 'b', 'c', 'd']
            >>> list(("a", "b", "c", "d"))
            ['a', 'b', 'c', 'd']
            							

          • リスト内包表記( [x for x in iterable] など)の使用( iterableイテラブル)とは,構成要素を一度に一つずつ返すことができるオブジェクト)
            >>> [x for x in "abcd"]
            ['a', 'b', 'c', 'd']
            							

            リストに対しては,先に述べた共通のシーケンス演算全てに加え,以下に述べるメソッドを使用することができます.

          • sort(*, key=None, reverse=None) : 項目間の < 比較のみを用いてリストをソート.2 つの引数をキーワード引数としてのみ渡せる.key は 1 引数をとる関数を指定し,リストのそれぞれの要素から比較キーを取り出すのに使用(例えば,key=str.lower).また,reverse は,ブール値であり,True に設定された場合,リストの要素は各比較が反転したように並び替えられる.
            >>> s = [1, 4, 3, 2, 5]
            >>> s.sort()
            >>> s
            [1, 2, 3, 4, 5]
            >>> s.sort(reverse=True)
            >>> s
            [5, 4, 3, 2, 1]
            							

        3. NumPy における配列

            数学関係のプログラムにおいて,拡張モジュール NumPy がよく使用されています.配列(または,行列)は,多くの分野で頻繁に使用されています.Python において多次元配列を表現するには,多重のリストが利用されます.リストでは,各セル毎に異なるオブジェクトを保持したり,各次元毎に要素数が異なるリストを生成できるなど,非常に汎用的なリストを実現できます.しかし,リンクでセルを結合した形式でメモリ上に保持されますので,処理速度の点で問題になります.

            numpy.ndarray モジュールでは,C/C++ の配列と同様,メモリの連続領域上に確保されます.また,各要素の型はすべて同じで,かつ,各次元ごとの要素数が等しくなければなりません.このことによって,より高速な処理が可能になっています.Python 内にも,リスト内に同じ型のデータだけを保持し,処理の高速化を狙った array オブジェクトが存在しますが,多次元配列への対応が多少面倒です.

            また,要素毎に何らかの処理をしたいような場合,例えば,各要素の平方根を計算したい場合,Python や C/C++ においては,繰り返しのプログラムを書く必要があります.しかし,numpy.ndarray モジュールには,ユニバーサル関数が準備されています.配列に対してこれらの関数を適用すると,自動的に,配列の各要素に対して希望する処理を適用してくれます.このことによって,プログラムの記述がかなり容易になるはずです.

            NumPy における配列を生成する最も基本的な方法は,
          numpy.array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
          						
          を利用する方法です.ここで,object はリストタプルです.また,dtype はデータの型を表し,numpy.bool,numpy.int,numpy.float,numpy.complex などが使用されます.生成された array オブジェクトは,以下に示すようなインスタンス変数を持っています.

          • dtype : データの型.numpy.bool,numpy.int,numpy.float,numpy.complex など

          • itemsize : 1 要素のバイト数

          • nbytes : 配列全体のバイト数

          • ndim : 配列の次元

          • shape : 配列の形をタプルで表現.例えば,要素数が 3 の 1 次元配列では (3,),2 行 3 列の配列では (2, 3) となる.

          • size : 配列の全要素数

            下に示す例における 2 行目の x のように指定すると,すべての要素は整数とみなされます.その結果,問題が起こる場合もありますので,浮動小数点数として扱いたい場合は,3 行目の z のように小数点を付加するか,または,4 行目の y のようにデータの型を指定してください.また,1 次元配列を,下の例における 2,3 行目のように宣言すると,それが,1 行 3 列なのか,あるいは,3 行 1 列 なのかが明確になりません.それを明確にしたい場合は,変数 u,v のような方法を使用してください.
          >>> import numpy as np   # この方法が良く利用される
          >>> x = np.array([1, 2, 3])  # (1 行 3 列) or (3 行 1 列) ?
          >>> z = np.array([1.0, 2, 3])
          >>> y = np.array([[1, 2, 3], [4, 5, 6]], np.float)
          >>> x.dtype, y.dtype, z.dtype
          (dtype('int32'), dtype('float64'), dtype('float64'))
          >>> x.ndim, y.ndim
          (1, 2)
          >>> x.shape, y.shape
          ((3,), (2, 3))
          >>> u = np.array([[1, 2, 3]])  # 1 行 3 列
          >>> v = np.array([[1], [2], [3]])  # 3 行 1 列
          >>> u.shape, v.shape
          ((1, 3), (3, 1))
          						
            また,特別な初期値を持った配列,特別な配列を生成するメソッド,簡単な生成方法を行うメソッドなどが多数存在します.

          • numpy.zeros(shape, dtype=None) : すべての要素が 0 である配列

          • numpy.ones(shape, dtype=None) : すべての要素が 1 である配列

          • numpy.empty(shape, dtype=None) : すべての要素の値が不定である配列

          • numpy.zeros_like(a, dtype=None)
            numpy.ones_like(a, dtype=None)
            numpy.empty_like(a, dtype=None) : 各々,既に作成した配列 a と同じ大きさで,かつ,すべての要素を 0,すべての要素を 1,または,すべての要素を不定にした配列

          • numpy.arange([start, ]stop, [step, ]dtype=None) : arange は,組み込み関数 range とほぼ同じ使用方法である.

          • ndarray.copy(order='C') : 配列オブジェクトの深いコピー

          • numpy.diag(v, k=0) : 配列 v から対角,または,それに近い要素から配列を生成.k が 0 の時は対角要素から,正の時は対角要素の k 個上の要素から,また,負の時は対角要素の k 個下の要素からなる配列を生成.

          • numpy.eye(n, m=None, k=0, dtype=<type 'float'>) : n 行 m 列( m を省略すると n に等しくなる)の配列の対角要素を 1 に設定する.k に正または負の値を設定すると,対角要素ではなく,対角要素の k 個上(正の場合),または,下(負の場合)の要素を 1 に設定する.

          • numpy.identity(n, dtype=None) : n 次元の対角要素だけが 1 である配列.

          • numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) : [start, stop] 区間を等分割した num 個の点(始点及び終点を含む)からなる配列.

          • numpy.random.randint(low, high=None, size=None, dtype='l') : 各要素の値を乱数によって決めた配列.

          • numpy.tile(A, reps) : A を reps 回繰り返した配列.

          • numpy.tri(n, m=None, k=0, dtype=<type 'float'>) : n 行 m 列( m を省略すると n に等しくなる)の下三角の配列.k が 0 の時は対角要素まで,正の時は対角要素の k 個上まで,また,負の時は対角要素の k 個下までの要素を 1 に設定する.

            配列に対しても,加減乗除,余り,べき乗などの演算が可能です.対応する要素毎,または,要素毎に目的とする演算が行われます.
          >>> import numpy as np   # この方法が良く利用される
          >>> a = np.array([[1, 2], [3, 4]])
          >>> b = np.array([[1, 0], [0, 1]])
          >>> a + b
          array([[2, 2],
                 [3, 5]])
          >>> a * b
          array([[1, 0],
                 [0, 4]])
          >>> a ** 2
          array([[ 1,  4],
                 [ 9, 16]])
          >>> a * 2
          array([[2, 4],
                 [6, 8]])
          >>> a / 2
          array([[ 0.5,  1. ],
                 [ 1.5,  2. ]])
          						

            また,ほとんどの math モジュールに対応するユニバーサル関数が用意されていますので,配列の各要素に同じ演算を簡単に実行できます.
          >>> import numpy as np   # この方法が良く利用される
          >>> a = np.array([[1, 2], [3, 4]])
          >>> np.sqrt(a)
          array([[ 1.        ,  1.41421356],
                 [ 1.73205081,  2.        ]])
          						

            行列matrix )は,配列と似ていますが同じものではありません.例えば,先に述べた配列どうしの乗算(要素どうしの乗算)は,行列どうしの乗算とは異なります.行列としても演算を行いたい場合は,
          class numpy.matrix(data, dtype=None, copy=True)
          						
          を使用する必要があります.同様に,ベクトルvector )も,3 行 1 列(列ベクトル),または,1 行 3 列(行ベクトル)の行列として定義する必要があります.data が配列の場合は,同じ形の行列を生成してくれます.なお,配列に対して適用できる関数のほとんどは,行列に対しても適用できます.
          >>> import numpy as np   # この方法が良く利用される
          >>> A = np.matrix([[1, 2], [3, 4]])   # 2 行 2 列の行列
          >>> B = np.matrix([[1, 0], [0, 1]])   # 2 行 2 列の行列
          >>> A * B   # 行列の積
          matrix([[1, 2],
                  [3, 4]])
          >>> A * 2   # スカラーをかける
          matrix([[2, 4],
                  [6, 8]])
          >>> A / 2   # スカラーで割る
          matrix([[ 0.5,  1. ],
                  [ 1.5,  2. ]])
          >>> A ** 2   # A * A
          matrix([[ 7, 10],
                  [15, 22]])
          >>> u = np.matrix([[1, 2, 3]])   # 1 行 3 列の行列(行ベクトル)
          >>> v = np.matrix([[1], [2], [3]])   # 3 行 1 列の行列(列ベクトル)
          >>> u * v   # 行列の積(内積に相当する演算)
          matrix([[14]])
          						

        4. range 型

            range 型は,数の変更可能なシーケンスを表し,一般に for ループにおいて,特定の回数のループを実行するために使われます.range 型のオブジェクトは,組み込み関数,

          class range(stop)
          class range(start, stop[, step])

          によって生成可能です.ただし,start,stop,step 共に,整数である必要があります.step 引数が省略された場合のデフォルト値は 1,start 引数が省略された場合のデフォルト値は 0 です.各引数の値は,各々,インスタンス変数 start,stop,step によって知ることができます(変更不可能).
          >>> list(range(1, 10, 2))
          [1, 3, 5, 7, 9]
          >>> list(range(10, -3, -1))
          [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2]
          >>> r = range(1, 10, 2)
          >>> r.step
          2
          >>> r[2]
          5
          						

        5. bytearray 型

            bytearray オブジェクトの要素は,8-bit,1 バイトであり,0 <= x < 256 の範囲の整数で表現されます.bytearray に専用のリテラル構文はありませんので,組み込み関数を使って作成します.

          • 組み込み関数 bytearray() を使用し,空のオブジェクトを作成
            >>> bytearray()
            bytearray(b'')
            							

          • 組み込み関数 bytearray() を使用し,指定された長さの 0 で埋められた bytearray オブジェクトの生成
            >>> bytearray(5)
            bytearray(b'\x00\x00\x00\x00\x00')
            							

          • 組み込み関数 bytearray() と整数を要素とする iterable の利用.iterableイテラブル)とは,構成要素を一度に一つずつ返すことができるオブジェクトである.下の例では,range を使用している.
            >>> bytearray(range(5))
            bytearray(b'\x00\x01\x02\x03\x04')
            >>> bytearray([1, 2, 3, 4, 5])
            bytearray(b'\x01\x02\x03\x04\x05')
            							

          • 組み込み関数 bytearray() を使用し,既存のバイナリデータから生成
            >>> bytearray(b"abc")
            bytearray(b'abc')
            							

            bytearray に対しては,先に述べた共通のシーケンス演算全てに加え,以下に述べるメソッドを使用することができます.

          • capitalize : 最初の文字だけを大文字に変換
          • center : 中央揃い
          • count : 出現回数
          • decode : bytearray を文字列に変換
          • endswith : 指定した文字で終わっているか?
          • expandtabs : タブを半角スペースに変換
          • find : 文字列の探索
          • fromhex : 16 進表記文字列を bytearray に変換
          • hex : bytearray を 16 進表記に変換
          • index : 文字列の探索
          • isalnum : 英数字か?
          • isalpha : 英字か?
          • isdigit : 数字か?
          • islower : 小文字か?
          • isspace : スペースか?
          • istitle : タイトルケースか?
          • isupper : 大文字か?
          • join : 文字列の結合
          • ljust : 左揃え
          • lower : 小文字に変換
          • lstrip : 先頭文字の削除
          • partition : 文字列を前から見た最初の区切り文字で 3 分割
          • replace : 文字列の置換
          • rfind : 文字列の後方からの探索
          • rindex : 文字列の後方からの探索
          • rjust : 右揃え
          • rpartition : 文字列を後ろから見た最初の区切り文字で 3 分割
          • rsplit : 区切り文字で文字列を分割
          • rstrip : 末尾の文字の削除
          • split : 区切り文字で文字列を分割
          • splitlines : 文字列を改行で分割
          • startswith : 指定した文字で始まっているか?
          • strip : 先頭及び末尾の文字を削除
          • swapcase : 大文字と小文字の変換
          • title : タイトルケースに変換
          • upper : 大文字に変換
          • zfill : 0 で左詰

    2. 集合型( set )

        set オブジェクトは,ハッシュ可能な(変更不可能な)オブジェクトの順序のない集まりであり,数学における集合に相当します.従って,ある要素が含まれるか否か,要素の数を得る,等に相当する演算は可能ですが,添え字,スライスなど,シーケンス型に対して使用されるような操作は不可能です.

        ハッシュ可能なオブジェクトとは,そのオブジェクトが存在する期間中変わらないハッシュ値を持ち,他のオブジェクトと比較ができるオブジェクトです.ハッシュ可能なオブジェクトは辞書キーや集合のメンバーとして使えます.辞書や集合のデータ構造は内部でハッシュ値を使っているからです.Python の変更不可能なオブジェクトはハッシュ可能ですが,変更可能なオブジェクト,例えばリスト辞書はハッシュ不可能です.

        set および frozenset という 2 種類の集合型が存在します.set は変更可能な集合型であり,要素の追加や削除が可能です.変更可能なため,ハッシュ値を持たず,辞書のキーや他の集合の要素として用いることができません.一方,frozenset 型は変更不可能であり,ハッシュ可能です.作成後に内容を改変できないため,辞書のキーや他の集合の要素として用いることができます.

        set は,要素を波括弧中にカンマで区切って列挙する(空の set は波括弧だけ)ことによって生成できます.また,set および frozenset は,組み込み関数,

      class set([iterable])
      class frozenset([iterable])

      を使用して生成することも可能です.iterable が指定されないと,空の集合が作成されます.iterableイテラブル)とは,リストタプルrange など,構成要素を一度に一つずつ返すことができるオブジェクトです.
      >>> {}   # 空の set
      {}
      >>> {1, 2, 3}
      {1, 2, 3}
      >>> {1, 2, 3, 3, 3}   # 同じ要素は含まない
      {1, 2, 3}
      >>> set([1, 2, 3])
      {1, 2, 3}
      >>> frozenset([1, 2, 3])
      frozenset({1, 2, 3})
      				
        set および frozenset のオブジェクトに対しては,以下に示す操作が可能です.なお,union(),intersection(),difference(),symmetric_difference(),issubset(),issuperset() メソッドは,任意のイテラブルを引数(set1,set2,・・・)として受け付けますが,それらのメソッドを演算子を使用して実現した場合は,引数は集合でなくてはなりません.

      • x in set : 要素を含む
      • x not in set : 要素を含まない
      • set < set1 : 真部分集合?
      • set > set1 : 真部分集合?
      • copy : 浅いコピー
      • difference : 集合 s に含まれ,集合 si に含まれない要素からなる集合
      • intersection : 積集合(共通集合)
      • isdisjoint : 積集合(共通集合)が空?
      • issubset : 部分集合?
      • issuperset : 部分集合?
      • len : 要素数
      • symmetric_difference : いずれか一方だけの集合に含まれる要素からなる集合
      • union : 和集合

    3. マッピング型(辞書型)

        マッピングmapping )オブジェクトは.ハッシュ可能な値であるキーと任意のオブジェクトのペアから構成されます.現在,標準のマッピング型は辞書dictionary )だけです.辞書のキーは,ほぼ,任意の値です.ただし,ハッシュ可能でない値,つまり,リストや辞書など変更可能な型はキーとして使用できません.

        辞書は,key : value 対をカンマで区切り,波括弧「 { } 」でくくることで作成できます.また,組み込み関数,

      class dict(**kwarg)
      class dict(mapping, **kwarg)
      class dict(iterable, **kwarg)

      を使用することによっても可能です.iterable のそれぞれの要素自身は,2 個のオブジェクトを持つイテラブルでなければなりません.それぞれの要素の最初のオブジェクトは新しい辞書のキーになり,2 番目のオブジェクトはそれに対応する値になります.同一のキーが 2 回以上現れた場合は,そのキーの最後の値が新しい辞書での対応する値になります.iterableイテラブル)とは,リストタプルrange など,構成要素を一度に一つずつ返すことができるオブジェクトです.

        キーワード引数 kwarg が与えられた場合,キーワード引数とその値が mapping または iterable から作成された辞書に追加されます.既に存在しているキーが追加された場合,キーワード引数の値は位置引数の値を置き換えます.

        以下に示す例は,空の辞書を生成する場合を除き,すべて同じ辞書を生成します.
      >>> d = {}   # 空の辞書
      >>> d = dict()   # 空の辞書
      >>> d = {"aaa" : 10, "bbb" : 20, "ccc" : 30}   # key:value 対と波括弧の利用
      >>> d = dict(aaa = 10, bbb = 20, ccc = 30)   # kwarg の利用
      >>> d = dict({"aaa" : 10, "bbb" : 20, "ccc" : 30})   # mapping の利用
      >>> d = dict({"aaa" : 10, "bbb" : 20}, ccc = 30)   # mapping と kwarg
      >>> d = dict([("aaa" , 10), ("bbb" , 20), ("ccc" , 30)])   # iterable の利用
      				
        辞書型のオブジェクトに対しては,以下に示す操作が可能です.

      • key in dic : key を持っているか?
      • key not in dic : key を持っていないか?
      • dic[key] : key に対応する値
      • dic[key] = value : key に対応する値を value に設定
      • clear : 全項目を削除
      • copy : 浅いコピー
      • del dic[key] : key で示される項目を削除
      • fromkeys : 新しい辞書を作成
      • get : キーに対応する値
      • items : 項目のビュー
      • iter : キーに関するイテレータ
      • kyes : キーのビュー
      • len : 項目数
      • pop : キーに対応する項目の取り出しと削除
      • popitem : 任意の項目を削除
      • setdefault : キーに対応する項目の取り出しまたは追加
      • update : 辞書の更新
      • values : 値のビュー
  5. 入出力と文

    1. 入出力

      1. 標準入出力

          コマンドプロンプト上でデータを変数に入力するためには(標準入力sys.stdin からの入力),組み込み関数 input を使用します.引数を記述すると,それが末尾の改行を除いて標準出力に書き出され,入力された 1 行を読み込み,文字列に変換して返します(末尾の改行を除去).また,変数の値などを標準出力sys.stdout )に表示するためには,組み込み関数 print を使用します.print は,与えられたオブジェクトを,スペースで区切り,標準出力に表示し,最後に改行します.
        01	>>> a = input("data? ")
        02	data? 10 3.141592654 abc
        03	>>> b = a.split()
        04	>>> b
        05	['10', '3.141592654', 'abc']
        06	>>> x = int(b[0])
        07	>>> y = float(b[1])
        08	>>> z = b[2]
        09	>>> print(x, y, z)
        10	10 3.141592654 abc
        11	>>> str = "x = {0:3d}, y = {1:.2f}, z = {2:s}".format(x, y, z)
        12	>>> print(str)
        13	x =  10, y = 3.14, z = abc
        					
        01,02 行目

          01 行目のコマンドによって,02 行目のように,画面上に「 data? 」というメッセージが出力されます.「 10 3.141592654 abc 」を入力し改行を行うと,入力した結果が文字列として変数 a に代入されます.

        03 行目~ 05 行目

          入力された文字列には,3 つのデータが含まれていますので,文字列型に対するメソッド split を使用して分離します.分離されたデータは,リストとして返されます.リストは,C/C++ の配列などと似たデータ構造であり,複数のデータを取り扱うことができます.06 行目~ 08 行目に示すように,リスト内の i 番目のデータを添え字 [i-1] で参照することができます.

        06 行目~ 08 行目

          数値データは,文字列のままでは演算等に使用できませんので,組み込み関数 intfloat を使用して,整数や浮動小数点数に変換します.

        09,10 行目

          組み込み関数 print を使用して,3 つの変数の値を出力しています.

        11 行目~ 13 行目

          データを書式化して出力したい場合は,文字列型に対するメソッド format を使用します.format は,C/C++ の printf に似た方法によって書式化を実行します.この例では,整数は 3 桁で,また,浮動小数点数は小数点以下 2 桁で出力します.
          以下に示す内容のスクリプトファイルを実行すると,キーボードから入力されたデータを "end\n" が入力されるまで,画面に表示続けます.
        # -*- coding: UTF-8 -*-
        import sys
        for line in sys.stdin :
        	if line == "end\n" :
        		break
        	else :
        		print(line)
        			# 以下の文とほぼ同じ
        line = ""
        while line != "end\n" :
        	print(line)
        	line = sys.stdin.readline()
        					

      2. ファイル入出力

          ここでは,ファイル入出力の際必要となる基本的な関数やメソッドについて説明します.

        • open('file_name', 'w')ファイルオブジェクト f を返す.通常,2 つの引数を伴って呼び出される.最初の引数はファイル名の入った文字列である.2 つ目の引数,mode 引数も文字列であり,ファイルをどのように使用するかを示す数個の文字が入っている.ファイルが読み出し専用なら 'r',書き込み専用なら 'w' とする.'a' はファイルを追記用に開き,ファイルに書き込まれた内容は自動的にファイルの終端に追加される.'r+' はファイルを読み書き両用に開く.mode 引数を省略すると,'r' であると見なされる.通常,ファイルはテキストモードで開かれるが,JPEG ファイルや EXE ファイルのようなバイナリデータの場合は,mode に 'b' を付け,バイナリモードで開く必要がある.

        • f.close() : ファイルオブジェクト f を閉じる.

        • f.closed : ファイルオブジェクト f が閉じられていれば True に設定される.

        • f.read([size]) : 最大 size バイトのデータを読み出し,文字列(テキストモードの場合),または,bytes オブジェクト(バイナリーモードの場合)として返す.size が省略されたり負の数であった場合,ファイルの内容全てを読み出して返す.また,ファイルの終端に達していた場合,空の文字列( '' )を返す.

        • f.readline() : ファイルから 1 行だけ読み取る.なお,改行文字( \n )は読み出された文字列の終端に残る.

        • f.write(object) : object の内容をファイルに書き込み,書き込まれた文字数を返す.オブジェクトの型は,書き込む前に,文字列(テキストモード),または,bytes オブジェクト(バイナリーモード)に変換しなければならない.

        • f.seek(offset[, from_what]) : ファイルオブジェクトの位置を変更する.位置は from_what によって指定された値に offset を加えて計算される.from_what の値が 0 ならばファイルの 先頭から,1 ならば現在のファイル位置,2 ならばファイルの終端を基準点とする.from_what のデフォルトは 0 である.

          以下に示すのは,上で述べた関数やメソッドの簡単な使用例です.
        >>> f = open("test.txt", "w")   # 出力のためにオープン
        >>> f.write("10 3.1492654 abc\n菅沼義昇\n")
        22
        >>> f.close()
        >>> f = open("test.txt", "r")   # 入力のためにオープン
        >>> f.read()
        '10 3.1492654 abc\n菅沼義昇\n'
        >>> f.seek(0)   # ファイルの先頭に移動
        0
        >>> f.readline()
        '10 3.1492654 abc\n'
        >>> f.readline()
        '菅沼義昇\n'
        >>> f.readline()
        ''   # ファイルの終わりを示す
        >>> f.close()
        					
          ファイルの内容すべてを読み込むため,次の例のように,標準関数 iter を使用した方法がしばしば使用されます.
        >>> with open('test.txt') as fp:
        ...     for line in iter(fp.readline, ''):
        ...             print(line,end="")
        ...
        10 3.1492654 abc
        菅沼義昇
        					
          数値データを要素と持つリスト(配列)を扱いたい場合,拡張モジュール NumPy がインストールされていると,以下に示すように,配列に対する入出力を簡単に行うことができます.
        >>> import numpy as np
        >>> a = np.array([[1, 2, 3], [4, 5, 6]])   # 2 行 3 列
        >>> np.savetxt('test.txt', a)   # 配列 a の出力
        >>> b = np.loadtxt('test.txt')   # 配列 b への入力
        >>> b
        array([[ 1.,  2.,  3.],
               [ 4.,  5.,  6.]])
        					

    2. 単純文

      1. 代入文

          Python のほとんどのデータは,クラスのオブジェクトです.変数が示す場所(アドレス)にデータ自身が記憶されているわけではなく,変数はデータ(オブジェクト)が記憶されている場所への参照(場所のアドレス)を表しています.代入においては,データをコピー(新しく生成)してそのデータに対する参照を代入しているのか,または,データそのものはすでに存在するものを使用し,そのデータに対する参照を代入しているのかといった違いに注意する必要があります.まず最初は,整数や浮動小数点数などの基本的なデータに関する説明です.
        		# 整数の場合,文字列の場合も同じ
        01	>>> a = 10
        02	>>> b = 10
        03	>>> a == b, a is b
        04	(True, True)
        05	>>> b = a
        06	>>> a == b, a is b
        07	(True, True)
        08	>>> b = 20
        09	>>> a == b, a is b
        10	(False, False)
        11	>>> a, b
        12	(10, 20)
        		# 浮動小数点数の場合,虚数(複素数)の場合も同じ
        13	>>> c = 1.2
        14	>>> d = 1.2
        15	>>> c == d, c is d
        16	(True, False)
        17	>>> d = c
        18	>>> c == d, c is d
        19	(True, True)
        20	>>> d = 1.3
        21	>>> c == d, c is d
        22	(False, False)
        23	>>> c, d
        24	(1.2, 1.3)
        					
          代入とは,= 記号の右辺で得られた結果を左辺で指定した変数が示す領域に記憶することです.01,02 行目においては,整数リテラル 10 が変数 a,b が示す領域に記憶されます.03,04 行目を見ると,値の比較においても,オブジェクトの比較においても,両者は等しくなっています.このことは,整数リテラル 10 が記憶領域のいずれかの場所にただ一つだけ記憶されており,変数 a,b はその(オブジェクトの)アドレスを指していることになります.つまり,変数 a,b は,C/C++ におけるポインタと非常に似ています(下の左図).従って,変数 b の値を変数 a に代入しても( 05 行目),その結果は変わりません.また,変数 b の値を変更すると( 08 行目),変数 b は異なる整数リテラル 20 を指すことになり,両者はいずれの比較においても異なってきます( 09,10 行目,下の右図).当然,変数 b の値を変更しても,変数 a の値は変化しません( 11,12 行目).下の左図の状態において,リテラル 10 を直接修正すれば,変数 a と b の値が同時に変化するはずですが,それを実行する演算子が存在しない,リテラルの値を修正できない,などの点から,Python では不可能です.

          しかし,浮動小数点の場合は多少異なってきます.変数 c や d がポインタであることに違いはないのですが,13 行目~ 16 行目から明らかなように,全く同じ値のリテラルであっても,異なる場所に記憶されている(異なるオブジェクトである)ことを意味します(下の左図).ただし,変数 d を変数 c に代入すれば,整数の場合と同じような状態になります( 17 行目~ 19 行目,下の右図).

          次に,リストのオブジェクトを代入する場合について考えてみます.下に示すプログラムの 1 ~ 2 行目,または,3 行目,いずれの方法で代入を行っても,4 行目のように y の要素を変更した場合,変化するのは y の要素だけです.この関係のイメージは,下図のようになります.

        >>> x = [1, 2, 3]
        >>> y = [1, 2, 3]
        >>> # x, y = [1, 2, 3], [1, 2, 3]
        >>> y[0] = 10
        >>> print(x, y)
        [1, 2, 3] [10, 2, 3]
        					
          しかし,下に示すプログラムの 1 ~ 2 行目,または,3 行目,いずれか方法で代入を行った場合,4 行目のように y の要素を変更した場合,対応する x の要素も変化します.これは,これらの方法で代入を実行した場合,オブジェクトに対する参照(アドレス)がコピーされ,同じオブジェクトを指すことになっているからです.C/C++ 風に言えば,同じオブジェクトに対するポインタがコピーされ代入されたことになります.この関係のイメージは,下図のようになります.

        >>> x = [1, 2, 3]
        >>> y = x
        >>> # x = y = [1, 2, 3]
        >>> y[0] = 10
        >>> print(x, y)
        [10, 2, 3] [10, 2, 3]
        					
          これを避けるためには,2 行目に示すように,copy メソッドを使用し,x が参照しているオブジェクトのコピー(浅いコピー)を新たに生成し,それに対する参照を y に代入することです.2 行目の処理は,copy モジュールを使用した 3 ~ 4 行目の処理と同等です.この処理によって,最初に示した代入文と同じような状態になり,y の値を変更しても x の値は変化しません.
        >>> x = [1, 2, 3]
        >>> y = x.copy()   # y = x[:] と同じ
        >>> # import copy
        >>> # y = copy.copy(x)
        >>> y[0] = 10
        >>> print(x, y)
        [1, 2, 3] [10, 2, 3]
        					
          しかし,以下に示すような 2 次元配列に対しては,浅いコピーによって,オブジェクト内に存在するオブジェクトの参照(アドレス,下図における ad11 と ad12 の部分)をコピーしているだけですので,同じ問題が発生します.

        >>> x = [[1, 2, 3], [4, 5, 6]]
        >>> y = x.copy()
        >>> y[0][0] = 10
        >>> print(x,y)
        [[10, 2, 3], [4, 5, 6]] [[10, 2, 3], [4, 5, 6]]
        					
          これを避けるためには,オブジェクト内に存在するオブジェクトに対しても,浅いコピーと同じ処理を行ってやることです.それが,深いコピーです(下図参照).

        >>> import copy
        >>> x = [[1, 2, 3], [4, 5, 6]]
        >>> y = copy.deepcopy(x)
        >>> y[0][0] = 10
        >>> print(x, y)
        [[1, 2, 3], [4, 5, 6]] [[10, 2, 3], [4, 5, 6]]
        					

      2. del 文

          オブジェクトを削除します.
        >>> a, b, c = 10, 20, 30
        >>> a, b, c
        (10, 20, 30)
        >>> del a, b
        >>> a, b, c
        Traceback (most recent call last):
          File "%lt;stdin>", line 1, in <module>
        NameError: name 'a' is not defined
        					

      3. import 文

          モジュールを取り込みます.
        >>> import math   # math モジュールの取り込み
        >>> math.sqrt(2)
        1.4142135623730951
        >>> import math as ma   # math モジュールを ma というモジュール名として取り込む
        >>> ma.sqrt(2)
        1.4142135623730951
        >>> from math import sqrt, fabs   # math モジュールからメソッド sqrt,fabs を取り込む
        >>> sqrt(2)
        1.4142135623730951
        >>> fabs(-10)
        10.0
        >>> from math import *   # math モジュールからすべてのメソッドを取り込む
        >>> sqrt(2)
        1.4142135623730951
        >>> pow(2, 10)
        1024.0
        					

      4. pass 文

          何も行わない文です.
        >>> a = 10
        >>> def func(x) : pass
        ...
        >>> func(a)
        >>> if a == 10:
        ...    pass
        ... else:
        ...    print("test")
        ...
        >>>
        					

    3. 複合文

      1. if 文

          if 文は,式i を順に評価していき,式i が True であれば 文i を実行し,他の部分は実行しません.いずれも True でなく.else 以下が記述されていた場合は,else の後の文を実行します.いずれの文も複数の文から構成されていても構いませんが,スペースまたはタブを使用して,同じレベルの字下げを行う必要があります.ただし,文が一つの文である場合は,コロンの後ろに記述しても構いません.
        if 式1 : 
            文1
        [elif 式2 : 
            文2]
        ・・・・・
        [elif 式n : 
            文n]
        [else  : 
            文]
        					

      2. while 文

          while 文は,式を評価し,式が True である限り 文1 の実行を繰り返します.式が False になり,else 以下が記述されていた場合は 文2 を実行し,また,記述されていなかった場合は何も行わず,繰り返しを終了します.いずれの文も複数の文から構成されていても構いませんが,スペースまたはタブを使用して,同じレベルの字下げを行う必要があります.ただし,文が一つの文である場合は,コロンの後ろに記述しても構いません.

          文1 の実行の途中で break 文が実行されると,文1 の残りの部分を実行せず,現在実行中の while 文から抜け出します( else 以下は実行されない).また,文1 の実行の途中で continue 文が実行されると,文1 の残りの部分を実行せず,式の真偽評価に移ります.
        while : 
            文1
        [else  : 
            文2]
        					

      3. for 文

          for 文は,イテラブルオブジェクト内の要素が順に変数に代入され,要素が空になるまで,文1 が繰り返し実行されます.要素が空になり,else 以下が記述されていた場合は 文2 を実行し,また,記述されていなかった場合は何も行わず,繰り返しを終了します.いずれの文も複数の文から構成されていても構いませんが,スペースまたはタブを使用して,同じレベルの字下げを行う必要があります.ただし,文が一つの文である場合は,コロンの後ろに記述しても構いません.なお,iterableイテラブル)とは,リストタプルrange など,構成要素を一度に一つずつ返すことができるオブジェクトです.

          文1 の実行の途中で break 文が実行されると,文1 の残りの部分を実行せず,現在実行中の for 文から抜け出します( else 以下は実行されない).また,文1 の実行の途中で continue 文が実行されると,文1 の残りの部分を実行せず,次の要素による 文1 の実行に移ります.
        for 変数 in イテラブルオブジェクト : 
            文1
        [else  : 
            文2]
        					

      4. with 文

          with 文は,ブロックの実行をコンテキストマネージャによって定義されたメソッドでラップするために使われます.コンテキストマネージャは,コードブロックを実行するために必要な入り口および出口の処理を扱います.簡単に言えば,ブロックの実行を,簡単かつ安全に実行させるための文です.代表的な使い方として,様々なグローバル情報の保存および更新,リソースのロックとアンロック,ファイルのオープンとクローズなどが挙げられます.

          次に示すのは,ファイルのオープンとクローズの例です.with ブロックに入る際にファイルがオープンされ,ブロックを出ると自動的にファイルがクローズされます.
        >>> with open("test.txt", "r") as f :
        ...    a = f.read()
        ...
        >>> a
        '10 20 30\n菅沼義昇\n'
        >>> f.closed
        True   # 既にクローズされている
        					

      5. try 文

          try 文は,例外処理を行うための文です.以下の例は,適切な値が入力されるまで,入力を促すことが繰り返されます.
        # -*- coding: UTF-8 -*-
        while True :
            try :
                x = int(input("整数を入力して下さい: "))
                break
            except ValueError :
                print("   不適切なデータです!")
        print(x)
        					
  6. 関数

    1. 関数の定義

      1. 引数とデフォルト

          ここでは,関数の定義方法について,例を使用しながら説明していきます.まず,最初は,最も基本的な関数です.3 つのデータを受け取り,それらの和を返す関数です.以下に示すような内容のファイル test.py を作成し,Window のコマンドプロンプト上で,
        py -3 test.py [data]   # [ ] 内はオプション
        					
        と入力すれば結果が得られるはずです.関数は,本来,独立したプログラムです.しかし,関数を test.py 内に記述すると,関数内からその外側の変数を参照できてしまいます.そのため,関数は,別のファイル function.py 内に記述しています.
        01	# -*- coding: UTF-8 -*-
        02	def func(s1, s2 = 20, s3 = 30) :
        03		"""example of function"""
        04		s  = s1 + s2 + s3
        05		s1 = 100
        06		return s
        ----------------------------------
        07	# -*- coding: UTF-8 -*-
        08	from function import func
        09	import sys
        10	print(func.__doc__)
        11	p1 = 10
        12	print("sum = ", func(p1))   # func(s1 = 10) or func(10) でも可
        13	print("p1 = ", p1)
        14	print("sum = ", func(p1, s2 = 50))   # func(10, 50) でも可
        15	print(len(sys.argv), sys.argv[0])
        16	#print(len(sys.argv), sys.argv[0], sys.argv[1])   # オプションを付加した場合
        					
        02 行目

          関数の定義は,キーワード def で始まり,関数名 func の後ろの括弧の中に仮引数のリスト(この例では,s1,s2,s3 )が並びます.これらの仮引数は,関数を呼び出す際にも,実引数として,同じ位置,同じ順番で記述する必要がありますので,位置指定引数と呼ばれます.なお,変数名は異なっても構いません( 12,14 行目において,p1 が s1 に対応).

          引数に対しては,それらが省略されたときの値,つまり,デフォルト値を設定することができます(デフォルト引数).この例では,引数 s2 及び s3 に対して設定しています.その結果,12 行目では s2 及び s3 を省略,また,14 行目では s3 を省略していますが,正しく計算されています.なお,最初または中間にある位置指定引数,例えば,s1 または s2 に対してだけデフォルト値を設定することはできません.なお,Python には,関数名の多重定義機能はありません.

        03 行目

          関数の本体を記述する文の最初の行は文字列リテラルにすることもできます.その場合,この文字列は関数のドキュメンテーション文字列と呼ばれ,変数 __doc__ によって参照できます( 10 行目参照).

        05 行目

          先に述べたように,関数は,本来,独立したプログラムです.しかし,関数における処理をする際に何らかの情報が欲しい場合があります.その情報を引き渡す手段が引数です(外部からの情報を必要としない場合は引数を記述しなくて良い).基本的に,実引数の値がコピーされて,仮引数に渡されます.従って,実引数と仮引数は全く独立した変数(値)ですので,この例の場合,変数 s1 の値を変更しても,変数 p1 の値は変化しません( 13 行目に対する出力結果参照).この点は,実引数と仮引数の変数名が同じである場合も同様です.

        06 行目

          return 文は,関数を呼び出した先に結果を返すための文です.この例の場合は,s1,s2,s3 の和が戻され,12,14 行目の結果となります.なお,結果を戻さない場合は必要ありません.

        08 行目

          function モジュール内にある関数 func を取り込んでいます.

        09 行目

          15,16 行目のために必要です.

        12,14 行目

          Python では,引数の渡し方として,「 s2 = 50 」のような形をとることができますが,関数は独立したプログラムであるべきなのに,関数の仮引数の名前を使用するといった仕様はいかがなものでしょうか.

        15,16 行目

          変数 sys.argv には,C/C++ 風に言えば,main 関数の引数に対する情報が入っています.プログラムを実行する際,何らかの付加的情報を必要とする場合があります.そのようなとき,上に示した使用方法における [ ] 内の data のように,その情報を記述可能です.これらの情報は,変数 sys.argv に入れられて渡されます.オプションを記述しなかった場合( 15 行目)は,実行したファイル名だけが入っています.data というオプションを付加すると,変数 sys.argv のサイズは 2 となり,その名前も渡されます( 16 行目と一番最後の出力).

          このプログラムを実行すると,以下に示すような出力が得られます.
        example of function
        sum =  60
        p1 =  10
        sum =  90
        1 test.py
        #2 test.py data
        						
          次の例では,引数にリストを用い,引数 lt のデフォルト値が [] (空のリスト)に設定されています.このプログラムを実行すると,次のような結果が得られます.明らかに奇異に感じると思います.これは,リストに対してデフォルトを設定した場合,それが評価されるのは最初に関数が呼ばれたときだけだからです.
        [1]
        [1, 2]
        [1, 2, 3]
        					
        # -*- coding: UTF-8 -*-
        def func(a, lt = []) :
        	lt.append(a)
        	return lt
        ----------------------------------
        # -*- coding: UTF-8 -*-
        from function import func
        print(func(1))
        print(func(2))
        print(func(3))
        					
          しかし,次の例を見てください.上と全く同じようなプログラムです.異なるのは,引数がリストではなく整数になっているだけです.この場合は,期待したように,常に,引数 a の値に sum のデフォルト値 0 が加えられた結果が出力されます.このように,変数の型によって異なる行動を行うような方法は使用すべきではありません.誤りの原因となる恐れがあります.もちろん,Python の仕様も変更すべきです.少なくとも,上のプログラムにおいては,デフォルト値を設定すべきではありません.
        # -*- coding: UTF-8 -*-
        def func(a, sum = 0) :
        	sum += a
        	return sum
        ----------------------------------
        # -*- coding: UTF-8 -*-
        from function import func
        print(func(1))
        print(func(2))
        print(func(3))
        					

      2. 引数の型(リスト)
          デフォルト引数の例で示したプログラムと同様,リストを引数とする場合について考えてみます.まず,01 行目~ 03 行目の関数において,return 文がないことに注意してください.関数から戻る値がないにもかかわらず,06 行目において初期設定されたリストの値は,
        [1]
        [1, 2]
        [1, 2, 3]
        					
        のように変化しています.つまり,引数として渡されたデータを関数内で修正すると,その関数を呼んだ側の対応するデータも変化しています.これは,整数型のような単純変数は別として,リストのような場合は,C/C++ におけるアドレス渡しや参照渡しと同じような方法で,引数に渡されるからです.記述方法が単純変数と同じであるにもかかわらず,異なる結果になることは,プログラムの誤りの原因にもなりかねます.十分注意してください.
        01	# -*- coding: UTF-8 -*-
        02	def func(a, lt) :
        03		lt.append(a)
        ----------------------------------
        04	# -*- coding: UTF-8 -*-
        05	from function import func
        06	lt = []
        07	func(1, lt)
        08	print(lt)
        09	func(2, lt)
        10	print(lt)
        11	func(3, lt)
        12	print(lt)
        					

      3. 引数の型(関数)
          Python においては,関数も一つのオブジェクトです.従って,関数(のアドレス)を他の変数に代入すれば,その変数は関数と同じように使用できます( 14,15 行目).また,関数(のアドレス)を関数の引数としても使用可能です( 16,17 行目).
        01	# -*- coding: UTF-8 -*-
        02	def add(s1, s2) :
        03		s = s1 + s2
        04		return s
        05	def sub(s1, s2) :
        06		s = s1 - s2
        07		return s
        08	def add_sub(fun, s1, s2) :
        09		s = fun(s1, s2)
        10		return s
        ----------------------------------
        11	# -*- coding: UTF-8 -*-
        12	from function import add, sub, add_sub
        13	print(add(2, 3))   # 5
        14	kasan = add
        15	print(kasan(2, 3))   # 5
        16	print(add_sub(add, 2, 3))   # 5
        17	print(add_sub(sub, 2, 3))   # -1
        					

      4. 再帰呼び出し
          再帰呼び出しrecursive call )とは,関数内において,その関数自身を呼び出すことです.次の例においては,階乗の計算を再帰呼び出しによって実行しています.
        # -*- coding: UTF-8 -*-
        def kaijo(m) :
        	if m > 1 :
        		s = m * kaijo(m-1)	 # 自分自身を呼んでいる
        	else :
        		s = 1
        	return s
        ----------------------------------
        # -*- coding: UTF-8 -*-
        from function import kaijo
        m = input("nの値を入力して下さい ")
        n = int(m)
        print(str(n) + "の階乗は=" + str(kaijo(n)))
        					

      5. 可変個の引数
          可変個の引数を受け取る関数を定義することもできます.以下の例においては,2 個の引数を利用しています.送られてきた引数は,例に見るように,タプルとして処理されます.*var の後ろにも引数を設定することができますが,key = value という形をとるキーワード引数だけが許されます.
        # -*- coding: UTF-8 -*-
        def func(*var, p) :
        	print(var, p)   # (10, 20) 30 を出力
        ----------------------------------
        # -*- coding: UTF-8 -*-
        from function import func
        func(10, 20, p = 30)   # func(10, 20, 30) はエラー
        					
          上と同様,可変個のキーワード引数を持つ関数を定義することも可能です.以下の例( 2 つのキーワード引数を使用)に見るように,key は辞書型データとして処理されます.
        # -*- coding: UTF-8 -*-
        def func(**key) :
        	print(key)   # {'key1': 10, 'key2': 20} を出力
        ----------------------------------
        # -*- coding: UTF-8 -*-
        from function import func
        func(key1 = 10, key2 = 20)
        					
          位置指定引数,可変個の引数,及び,可変個のキーワード引数すべてを持つ関数を定義することも可能です.ただし,引数の順番は,下に示す例のように決まっています.
        # -*- coding: UTF-8 -*-
        def func(p1, p2 = 10, *var, **key) :
        	print(p1, p2)   # 1 5 を出力
        	print(var)   # (100, 200) を出力
        	print(key)   # {'key2': -2, 'key1': -1} を出力
        ----------------------------------
        # -*- coding: UTF-8 -*-
        from function import func
        func(1, 5, 100, 200, key1 = -1, key2 = -2)
        					

      6. ローカル変数とグローバル変数

          一般に,関数内で定義された変数は,関数内だけで有効です.しかし,場合によっては,複数の関数内で特定の変数を参照したい場合があります.この様な変数をグローバル変数,また,関数内だけで有効な変数をローカル変数と呼びます.基本的に,関数外で変数を定義すれば,その変数はグローバル変数となり,関数内からもその変数を参照・変更可能となります.下の例における 13 行目の変数 a が相当します.

          ただし,関数内においてグローバル変数を修正する場合は十分注意する必要があります.04 行目が存在しなければ,03,05 行目は,グローバル変数 a の値を出力します.しかし,04 行目によって,グローバル変数と同じ名前の新しいローカル変数が定義されたとみなされます.従って,03 行目は,未定義の変数 a の出力とみなされエラーになります.

          関数 func1 のような形で,関数内でグローバル変数の値を修正しようとすれば,新しいローカル変数の定義とみなされ,グローバル変数の値は変更されません.関数内においてグロ-バル変数の値を修正するためには,08 行目のような宣言が必要です.もしこの宣言がなければ,a は新しいローカル変数とみなされ,関数 func1 の場合と同様,09 行目でエラーになってしまいます.
        01	# -*- coding: UTF-8 -*-
        02	def func1() :
        03	#	print(str(a) + " in func1")   エラー
        04		a = 20
        05		print(str(a) + " in func1")
        06	
        07	def func2() :
        08		global a   # 記述しないとエラー
        09		print(str(a) + " in func2")
        10		a *= 10
        11		print(str(a) + " in func2")
        12	
        13	a = 10
        14	print(a)
        15	func1()
        16	print(a)
        17	func2()
        18	print(a)
        					
          上のプログラムを実行すると以下のような出力が得られます.
        10
        20 in func1
        10
        10 in func2
        100 in func2
        100
        					

    2. ジェネレータ関数

        ジェネレータは,イテレータ(順番にオブジェクトの要素を取り出すための演算子)を作成するための簡潔なツールです.簡単にジェネレータを生成したいときは,ジェネレータ式を利用できます.ジェネレータ式は,丸括弧を使用し,以下のような形になります.なお,引数が一つである関数の引数とする場合は,丸括弧を省略できます.
      (式 for 式 in イテラブルオブジェクト)   # for を多重に使用しても良い
      				
        次の例は,0 の 2 乗から 9 の 2 乗までを取り出すためのジェネレータ式です.ここで,next() は,イテレータの次の要素を取得するための組み込み関数です.
      >>> g = (pow(x, 2) for x in range(10))
      >>> list(g)
      [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
      >>> next(g)
      0
      >>> next(g)
      1
      >>> next(g)
      4
       ・・・・・
      >>> list(g)   # 要素を取り出した後は空
      []
      >>> sum(pow(x, 2) for x in range(10))   # 2 乗の和
      285
      				
        ジェネレータ関数は,通常の関数のように書かれますが,何らかのデータを返すときには yield 文が使われます.ジェネレータ関数が開始されると,最初の yield 式まで処理して一時停止し,呼び出し元へ yield 式で与えた値を返します.ここで言う一時停止とは,ローカル変数の束縛,命令ポインタや内部の評価スタック,そして例外処理を含むすべてのローカル状態が保持されることを意味します.再度,ジェネレータ関数が呼び出されて実行を再開した時,ジェネレータ関数は,yield 式がただの外部呼び出しであったかのように処理を継続します.以下に示す例では,指定した位置から,データを逆方向にイテレートしています.
      >>> def reverse(data, start) :
      ...     for index in range(start, -1, -1) :
      ...         yield data[index]
      ...
      >>> data1 = "abcde"
      >>> n = reverse(data1, 2)
      >>> next(n)
      'c'
      >>> next(n)
      'b'
      >>> for char in reverse(data1, 2) :
      ...     print(char)
      ...
      c
      b
      a
      				
  7. クラス

    1. クラスの定義

        C++ の用語で言えば,通常のクラスclass )のメンバー(変数及び関数)は public であり,どこからでも参照可能です.メンバー関数(メソッド)はすべて仮想関数です.メソッドの宣言では,生成されたオブジェクト自身を表す第一引数 self を明示しなければなりません.この引数は,メソッド呼び出しの際に暗黙の引数として渡されます.一般的に,「 self.var 」の形でメソッドの内側で定義される変数 var は,インスタンス変数と呼ばれ,各インスタンス固有の値を持つことが可能です.また,メソッドの外側で宣言され,かつ,self がつかないクラス変数は,そのクラスのすべてのインスタンスで同じ値を持ちます.
      01	# -*- coding: UTF-8 -*-
      02	class Example :
      03	    """A simple example of class"""   # クラスの説明
      04	    c_var = 12345   # クラス変数
      05	    def func(self, a) :
      06	        self.i_var = a   # インスタンス変数
      ----------------------------------
      07	# -*- coding: UTF-8 -*-
      08	from function import Example
      09	print(Example.__doc__)   # クラスの説明の表示
      10	x = Example()   # Example クラスのインスタンス(オブジェクト)の生成
      11	x.func(10)   # Example.func(x, 10) と等価
      12	y = Example()
      13	y.func(20)
      14	z = Example()
      15	z.func(30)
      16	print("最初の状態  x,y,z")
      17	print(Example.c_var, x.c_var, x.i_var)
      18	print(Example.c_var, y.c_var, y.i_var)
      19	print(Example.c_var, z.c_var, z.i_var)
      20	print("***w に x を代入***")
      21	w = x
      22	print("w の値変更  x,y,z,w")
      23	w.c_var = 100
      24	w.i_var = 40
      25	print(Example.c_var, x.c_var, x.i_var)
      26	print(Example.c_var, y.c_var, y.i_var)
      27	print(Example.c_var, z.c_var, z.i_var)
      28	print(Example.c_var, w.c_var, w.i_var)
      29	print("x の値変更  x,y,z,w")
      30	xf = x.func   # 関数に対するポインタ,普通の関数でもOK
      31	xf(50)
      32	x.c_var = 1000
      33	print(Example.c_var, x.c_var, x.i_var)
      34	print(Example.c_var, y.c_var, y.i_var)
      35	print(Example.c_var, z.c_var, z.i_var)
      36	print(Example.c_var, w.c_var, w.i_var)
      37	print("クラス変数値の変更  x,y,z")
      38	Example.c_var = 123
      39	print(Example.c_var, x.c_var, x.i_var)
      40	print(Example.c_var, y.c_var, y.i_var)
      41	print(Example.c_var, z.c_var, z.i_var)
      42	print(Example.c_var, w.c_var, w.i_var)
      				
      03 行目

        クラス本体を記述する文の最初の行は文字列リテラルにすることもできます.その場合,この文字列はクラスのドキュメンテーション文字列と呼ばれ,変数 __doc__ によって参照できます(以下に示すのは 09 行目による出力結果).
      	A simple example of class
      					
      10 行目~ 19 行目

        Example クラスのオブジェクト x,y,z を生成しています.インスタンス変数の値は異なりますが,クラス変数の値はすべて同じです.以下に示すのは,16 行目~ 19 行目による出力結果です.
      	最初の状態  x,y,z
      	12345 12345 10
      	12345 12345 20
      	12345 12345 30
      					
      20 行目~ 28 行目

        x を w に代入後,w のクラス変数及びインスタンス変数の値を変更しています.当然,w の値は変化しますが,x の値も変化しています.これは,x と w が同じオブジェクトを指していることも意味します.つまり,Python におけるオブジェクトは,C/C++ におけるポインタに似た性質を持つことになります.従って,関数に対する説明において述べたリストを引数とした場合と同様,クラスのオブジェクトを引数とした場合は,関数内でその値を変更すれば,関数を呼んだ側の値も変化します.以下に示すのは,20 行目~ 28 行目による出力結果です.
      	***w に x を代入***
      	w の値変更  x,y,z,w
      	12345 100 40
      	12345 12345 20
      	12345 12345 30
      	12345 100 40
      					
      29 行目~ 36 行目

        x と w は同じオブジェクトを指していますので,x の値を変化させても,上と同様なことが起こります.また,関数自体もポインタ(関数を指すアドレス)ですので,30,31 行目のようなことが可能です.以下に示すのは,29 行目~ 36 行目による出力結果です.
      	x の値変更  x,y,z,w
      	12345 1000 50
      	12345 12345 20
      	12345 12345 30
      	12345 1000 50
      					
      37 行目~ 42 行目

        クラス変数の値を変更すると( 38 行目),そのクラスのすべてのオブジェクトのクラス変数の値も変化します( 40,41 行目).ただし,23,32 行目のように,オブジェクトのクラス変数の値を直接変更した場合は,その影響を受けません( 39,42 行目に対する出力結果参照).この仕様も,誤りの原因になりやすく,問題です.以下に示すのは,37 行目~ 42 行目による出力結果です.
      	クラス変数値の変更  x,y,z
      	123 1000 50
      	123 123 20
      	123 123 30
      	123 1000 50
      					

    2. 初期化

        クラスに __init__() メソッドが定義されている場合,クラスのインスタンスを生成すると最初にこのメソッドが呼ばれます.C++ におけるコンストラクタに対応するメソッドです.
      # -*- coding: UTF-8 -*-
      class Complex() :
      	def __init__(self, re, im = 0.0) :
      		self.re = re
      		self.im = im
      	def add(self, v) :
      		x = Complex(self.re + v.re, self.im + v.im)
      		return x
      ----------------------------------
      # -*- coding: UTF-8 -*-
      from function import Complex
      x = Complex(1, 2)
      y = Complex(3)
      z = x.add(y)
      print((z.re, z.im))   # (4, 2.0)
      				

    3. 継承

        派生クラスを定義する方法は簡単です.以下に示すように,基底クラスとなるクラス名を括弧内に並べるだけです(多重継承が可能).また,BaseClassName.methodname(self, arguments) という形で,基底クラスのメソッドも簡単に呼び出すことができます.
      class DerivedClassName ( BaseClassName1, BaseClassName2, ・・・ ):
      				
        下の例では,Num を基底クラスとした 2 つの派生クラス,Int 及び Complex を定義しています.
      # -*- coding: UTF-8 -*-
      class Num :
      	name = "数値"
      	def __init__(self, v) :
      		self.v = v
      	def add(self, v) :
      		x = Num(self.v + v)
      		return x
      class Int(Num) :
      	name = "整数"
      class Complex(Num) :
      	name = "複素数"
      		# 親クラスのコンストラクタを呼びたい場合は Num.__init__(self, 値)
      	def __init__(self, re, im = 0.0) :
      		self.re = re
      		self.im = im
      	def add(self, v) :
      		x = Complex(self.re + v.re, self.im + v.im)
      		return x
      ----------------------------------
      # -*- coding: UTF-8 -*-
      from function import *
      x = Int(10)   # 基底クラス Num のコンストラクタ __init__ の継承により,変数 v に値が設定される
      print(x.v)   # 10
      y = x.add(20)   # 親クラス Num のメソッド add の継承
      print(y.v)   # 30
      u = Complex(1, 2)   # クラス Complex のコンストラクタ __init__ の利用
      print((u.re, u.im))   # (1, 2)
      v = Complex(3)
      print((v.re, v.im))   # (3, 0.0)
      w = u.add(v)   # クラス Complex のメソッド add の利用
      print((w.re, w.im))   # (4, 2.0)
      u.re = (Num.add(Num(u.re), 10)).v   # 基底クラスのメソッド add の利用
      print((u.re, u.im))   # (11, 2)
      print(u.name)   # クラス Complex のクラス変数 name の値(複素数)
      print(Num.name)   # 基底クラス Num のクラス変数 name の値(数値)
      				

    4. インスタントメソッド,クラスメソッド,スタティックメソッド

        今まで使用してきたメソッドはインスタントメソッドと呼ばれ,クラスのインスタント(オブジェクト)固有の処理を行うためのメソッドです.これ以外に,Python には,クラスメソッド,及び,スタティックメソッドが存在します.クラスメソッド,スタティックメソッドともに,インスタンス変数にはアクセスできません.

        クラスメソッドは,「 @classmethod 」を付与して関数を定義します.インスタンスメソッドの場合は,第一引数にオブジェクト自身 self が渡されますが,クラスメソッドの場合は,第一引数にクラスが渡されます.従って,クラスメソッドは渡ってきたクラスを使ってクラス変数にアクセスすることができます.継承時には,第一引数に子クラスが渡されるため,クラス変数は子クラスのクラス変数の値となります.

        スタティックメソッドは,「 @staticmethod 」を付与して関数を定義します.スタティックメソッドは,クラスが渡されないため,クラス変数にアクセスするためには,クラスを記述する必要があります.クラスを記述することによってクラス変数にアクセスするため,継承時においても,記述したクラスが親クラスか子クラスかによって参照先が変わります.

        下の例では,上で示した例における基底クラス Num にクラスメソッドとスタティックメソッドが追加してあります.クラスメソッドの場合は,クラスが引数として渡されますので,30,31 行目,いずれの場合においても,Complex クラスにおけるクラス変数 name の値「複素数」が出力されます.しかし,スタティックメソッドの場合は( 32,33 行目),基底クラス Num のスタティックメソッドがそのまま継承されるため,基底クラスのクラス変数 name の値「数値」がそのまま出力されます.
      01	# -*- coding: UTF-8 -*-
      02	class Num :
      03		name = "数値"
      04		def __init__(self, v) :
      05			self.v = v
      06		def add(self, v) :
      07			x = Num(self.v + v)
      08			return x
      09				# クラスメソッド
      10		@classmethod
      11		def class_method(cls) :
      12			print(cls.name)
      13				# スタティックメソッド
      14		@staticmethod
      15		def static_method() :
      16			print(Num.name)
      17	class Int(Num) :
      18		name = "整数"
      19	class Complex(Num) :
      20		name = "複素数"
      21		def __init__(self, re, im = 0.0) :
      22			self.re = re
      23			self.im = im
      24		def add(self, v) :
      25			x = Complex(self.re + v.re, self.im + v.im)
      26			return x
      ----------------------------------
      27	# -*- coding: UTF-8 -*-
      28	from function import *
      29	x = Complex(1, 2)
      30	Complex.class_method()
      31	x.class_method()
      32	Complex.static_method()
      33	x.static_method()
      				
  8. 変数の有効範囲(スコープ)

    01	# -*- coding: UTF-8 -*-
    02	
    03	#***************************/
    04	# 変数の有効範囲(スコープ) */
    05	#      coded by Y.Suganuma */
    06	#***************************/
    07	
    08	#******************/
    09	# クラス Example1 */
    10	#******************/
    11	class Example1 :
    12		c_var = 1000
    13	
    14		def __init__(self) :
    15			self.i_var = 2000
    16	
    17		def sub1(self) :
    18			print("sub1 c_var", self.c_var, "i_var", self.i_var)
    19	
    20	#******************/
    21	# クラス Example2 */
    22	#******************/
    23	class Example2(Example1) :
    24		def sub2(self) :
    25			print("sub2 c_var", self.c_var, "i_var", self.i_var)
    26	
    27	#***********/
    28	# 関数 sub */
    29	#***********/
    30	def sub() :   # この位置で定義する必要がある
    31		x = 40
    32		print("   sub x", x)
    33		print("   sub z", z)
    34	
    35	#***************/
    36	# main program */
    37	#***************/
    38			# ブロック
    39	x = 10
    40	z = 30
    41	if x > 5 :
    42		print("block x", x)
    43		x = 15
    44		y = 20
    45		print("block x", x)
    46		print("block y", y)
    47	else :
    48		print("block x", x)
    49		x = -15
    50		print("block x", x)
    51	sub()
    52	print("x", x)
    53	print("y", y)   # 最初の x が 1 の時は,y が未定義のためエラー
    54			# クラス
    55	ex = Example2()
    56	ex.sub1()
    57	ex.sub2()
    58	print("member( c_var )", Example2.c_var)
    59	print("member( i_var )", ex.i_var)
    			
      まず,39 行目において,変数 x が定義され(変数 x に値が代入され),10 で初期設定されています.この変数 x は,この位置から main プログラムが終わる 59 行目まで有効になります.42 ~ 46 行目の if ブロック内の 42 行目において,変数 x の値が出力されていますが,当然,その結果は,39 行目で宣言されたときの値になります.しかし,43 行目において,再び,変数 x が宣言されていますが,Python の場合は,C++ の場合とは異なり,39 行目で宣言された変数 x に置き換わることになります.従って,ここで宣言された変数 x の有効範囲は,main プログラムの終わりである 59 行目までになります.実際,52 行目における出力文では,43 行目において宣言された変数 x の値が出力されます.同様に,44 行目で宣言された変数 y の有効範囲も 59 行目までとなります.この例では,問題がありませんが,39 行目における変数 x の初期値を 5 以下に設定すると,48 ~ 50 行目が実行されることになります.そのブロック内では,変数 y が使用されていませんので,53 行目の出力文はエラーになってしまいます.変数が定義されているか否か(変数に値が代入されているか否か)の見極めが困難である場合も多いと思いますので,十分注意してください.

      51 行目において関数 sub を呼んでいます.31 行目では,変数 x を宣言(変数 x に値を代入)し,32 行目において,その値を出力しています.31 行目の宣言を行わなければ,変数 z と同様,main プログラム内の変数 x の値が出力されます.main プログラム内の変数 x ( 39 行目)の値を変更したい場合は,31 行目の前に,
    global x
    				
    という宣言をしておく必要があります.

      一般に,Python では,main プログラム内の変数は,33 行目に示すように,どの関数からも参照することができます(非常に危険だと思いますが).ただし,関数内で main プログラムと同じ変数を定義(変数に代入を行うことを意味する)したり,あるいは,新しい変数を定義した場合,それらの変数を main プログラムから参照することはできません( 52 行目に対応する出力結果参照).また,ある関数から,異なる関数内の変数を参照することも不可能です.このように,どの関数からも参照可能な変数をグローバル変数と呼びます.逆に,ある関数内だけで有効な変数を,ローカル変数と呼びます.以上,40 ~ 54 行目内の出力文(関数 sub 内の出力文を含む)によって,以下に示すような出力が得られます.
    block x 10
    block x 15
    block y 20
       sub x 40
       sub z 30
    x 15
    y 20
    				
      次に,クラスに付いて考えてみます.11 ~ 18 行目においてクラス Example1 が定義され,23 ~ 25 行目では,クラス Example1 を継承する形で,クラス Example2 が定義されています.なお,Python においては,すべての変数をクラス外から参照可能です( C++ において,public 指定を行っている状態).

      55 行目において,Example2 のインスタンス ex を生成し,56 行目では,クラス Example1 から継承した関数 sub1 を通して,2 つの変数を出力しています.また,57 行目では,クラス Example2 に追加された関数 sub2 を通して各変数を出力しています.いずれも,同じように出力されます.Python において,12 行目のような形で宣言された変数はクラス変数と呼ばれ,すべてのクラスのインスタンスで同じ値を持ち,クラス外部からでも,58 行目のような形で参照できます.また,15 行目のように,self を付加して宣言した変数は,インスタンス変数と呼ばれ,インスタンス毎に異なる値をとることが可能です.インスタンス変数は,59 行目のような形で,クラスの外部からも参照することができます.以上,55 ~ 69 行目内の出力文によって,以下に示すような出力が得られます.
    sub1 c_var 1000 i_var 2000
    sub2 c_var 1000 i_var 2000
    member( c_var ) 1000
    member( i_var ) 2000
    				

静岡理工科大学 菅沼ホーム Python と C/C++ 目次