はじめに
Pythonの基本的な書き方を記載します。
バージョンは3.4.3です。
コメント
コメントは "#" ではじまります。
# これはコメントです
数値
整数、浮動小数点数、複素数があります。
# 四則演算
2 + 3 # 5
2 - 3 # -1
2 * 3 # 6
# 整数の割り算は浮動小数点数になります
2 / 3 # 0.6666666666666666
# //演算で割り算後の整数部分が取り出せます
3 // 2 # 1
# **はべき乗です
2 ** 10 # 1024 2の10乗
# 複素数
(1+1j) + (2+2j) # (3+3j) 虚数単位はj、1jの1は省略不可
c = 1 + 2j
c.real #1.0 実部
c.imag #2.0 虚部
sequence
要素が番号順に並んだデータ構造です。
各要素は0からはじまる整数indexでアクセス可能です。
次のデータ構造はsequenceです。
- 文字列
- list
- tuple
- range
Listを例にしてsequenceを説明します。
l = [1,2,3]
l[0] # 1 要素0 indexは0ではじまる
l[2] # 3 要素2
l[-1] # 3 要素3 indexはマイナスでもOK
len(l) # 3 要素数
max(l) # 3 最大値
min(l) # 1 最小値
l.count(1) # 1 出現回数
1 in l # True 要素が含まれるかどうか
3 in l # False
1 not in l # False 要素が含まれないか、inの真偽反転
# 範囲を指定してListを返します
l[:] # [1,2,3] 全要素をListで返す
l[1:2] # [2] a:b形式でaからb-1までの要素をListで返す
l[0:] # [1,2,3] a:形式でaから最後までの要素をListで返す
l[:2] # [1,2] :b形式で先頭からb-1までの要素をListで返す
文字列
要素が文字であるsequenceです。
要素の変更はできません。
s = "string" # 文字列は"でくくる
s = 'string' # 'でもOK
# 整数indexで文字にアクセスできます
s[0] # 's'
# 要素は変更できません
s[0] = "S" # エラー
# 複数行の文字列は" or 'を3個並べたものでくくります
'''
複数行の
文字列
'''
# 文字列をつなげます
"a" + "b" # 'ab'
# 文字列を繰り返します
"a" * 2 # 'aa'
# 文字列を分割します
"1,2".split(",") # ['1', '2'] リストが返る
# 文字列を結合します
",".join(["1","2"]) # '1,2'
# 文字列を数値に変換します
int("0x10", 16) # 16 第2引数は基数
int("10") # 10 第2引数を省略すると基数10扱い
int("10", 2) # 2
float("1.2") # 1.2
# 数値を文字列に変換します
"dec:{0},hex:{0:X},bin:{0:b}".format(16) # 'dec:16,hex:10,bin:10000'
"{0:.2f}".format(3.1415) # '3.14'
list
任意のデータを要素にできるsequenceです。
要素を変更できます。
l = [1,2,3] # ,区切り、"[]"でくくる
l[0] # 1 要素0 indexは0ではじまる
l[2] # 3 要素2
l[-1] # 3 要素3 indexはマイナスでもOK
# 末尾に要素を追加します
ll = l + [4] # ll = [1,2,3,4] 要素を追加します(+)
l.append(4) # l = [1,2,3,4] 要素を追加します(append)
# 末尾から要素を取り出します
l = [1,2,3]
l.pop # 3 結果 l = [1,2]
# 要素の繰り返しを返します
l = [2]
l * 2 # [2,2]
# リストの初期化には内包表記というものが使えます
# []内にfor文を記載します
l = [x for x in range(10)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 多次元リスト
# 2次元:行列
m = [[row for row in range(2)] for col in range(3)] # [[0, 1], [0, 1], [0, 1]]
# 3次元
m = [[[row for row in range(2)] for col in range(3)] for mat in range(4)]
tuple
任意のデータを要素にできるsequenceです。
要素を変更できません。この点がListとの違いです。
t = (1,2,3) # ,区切り、"()"でくくる
t[0] = 10 # エラー、要素を変更できない
range
数値を要素にできるsequenceです。
要素を変更できません。for文と組み合わせて使います。
# range(x)で0~x-1を表します
# 0~9が表示されます
for i in range(10):
print(i)
# range(x, y)でx~y-1を表します
# 1~9が表示されます
for i in range(1, 10):
print(i)
# range(x, y, step)でx,x+step, x+2*step, ... (y-1まで)を表します。
# 1,3,5,7,9を表します。
for i in range(1, 10, 2):
print(i)
制御文
if
aaa < x < bbb
形式で比較条件が指定できます。
in
やis
演算が使用できます。
# if .. elif .. else
x = 1
if x == 1:
print("x == 1")
elif x == 2:
print("x == 2")
else:
print("else")
# result : x == 1
# < x < 演算
x = 5
if 1 < x < 6:
print("True")
else:
print("False")
# result : True
# in 演算
if 0 in [1, 2, 3]:
print("True")
else:
print("False")
# result : False
# not in 演算
if 0 not in [1, 2, 3]:
print("True")
else:
print("False")
# result : True
# is 演算、同じオブジェクトかどうかを判断します
if [1] is [1]:
print("True")
else:
print("False")
# result : False
l = [1,2,3]
ll = l
if l is ll:
print("True")
else:
print("False")
# result : True
for
break/continueは他の言語と同じです。
elseが特徴的です。for文を最後まで実行したときにelseが実行されます。
breakで止まった時はelseは実行されません。
# range
for i in range(10):
print(i)
# result : 0~10
# list
for i in [1, 2, 3]:
print(i)
# result : 1~3
# else/break
# elseをつけることができます。
# 最後までforを実行したときにelseが実行されます。
# breakしたときには実行されません。
for i in [1, 2, 3]:
print(i)
if i == 2:
break
else:
print("else")
# result : 1~2, elseは表示されない
while
forと同じくelseをつけることができます。
i = 0
while i < 10:
print(i)
if i == 1:
break
i = i + 1
else:
print("else")
# result : 0~1
関数
f(x=10, y=20)
など引数名を指定して関数を呼び出せます。
可読性がよくなり、引数順番を変えられます。
# 合計値を返す関数を定義します
def sum(l):
val = 0
for i in l:
val = val + i
return val
print(sum([1, 2, 3]))
# result : 6
# default引数を指定できます
def add(x=10, y=20):
return x + y
print(add())
# result : 30
# 引数名を指定して呼び出せます、引数順番を変えられます。
def sub(x, y):
return x - y
print(sub(y=20, x=10))
# result : -10
モジュール
クラスや関数が記載されたファイルをモジュールといいます。
拡張子は.pyです。モジュール名は.pyを除いたファイル名です。
よく使う機能をモジュールにまとめておくと再利用ができて便利です。
# importでモジュールを取り込みます。
import numpy as np # as で別名を定義
a = np.array([1,2,3]) # 別名 npでモジュールメンバを参照する
# 単にimportしたときにはモジュールメンバを参照するときには
# モジュール名(or別名)で修飾(e.g. np.array)する必要があります。
# fromを使うことで修飾を省略することができます。
from numpy import array
a = array([1,2,3]) # npなしでOK
# *ですべて指定することも可能
from numpy import *
クラス
クラスを定義すると対応するクラスオブジェクトが作成されます。
コンストラクタ名は__init__
です。引数にselfをとります。
selfとは自分自身のオブジェクトを参照するためのキーワードです。
クラスオブジェクトは以下を含みます
- クラス変数
- インスタンス変数
- クラスメソッド
- インスタンスメソッド
- スタティックメソッド
変数とメソッドはパブリック、プライベートスコープを持ちます。
名前の先頭に__
をつけるとプライベートになります。
プライベートなものはクラス外からはアクセスできません。
# クラスを定義します
class Test:
# クラス変数
i = "pub class var" # パブリック
__i = "prv class var" # プライベート
# インスタンスメソッド
def method(self):
print("pub inst method")
def __method(self):
print("prv inst method")
# クラスメソッド
@classmethod
def cls_meth(cls):
print("cls_meth")
# スタティックメソッド
@staticmethod
def stat_meth():
print("stat_meth")
# コンストラクタ
def __init__(self):
# インスタンス変数
self.j = "pub inst var" # パブリック
self.__j = "prv inst var" # プライベート
print("__init__")
# パブリック
print(Test.i) # クラス変数 class.name形式
print(self.i) # クラス変数 obj.name形式
print(self.j) # インスタンス変数 obj.name形式
self.method() # メソッド
# プライベート
print(self.__i) # クラス変数 class.name形式
print(self.__j) # インスタンス変数 obj.name形式
self.__method() # メソッド
# インスタンスを作成します
t1 = Test()
t2 = Test()
# 変数を参照します
print(Test.i) # 1 クラス変数 class.name形式
print(t1.i) # 1 クラス変数 obj.name形式
print(t1.j) # 2 インスタンス変数 obj.name形式
# 同じ名前のクラス変数、インスタンス変数が定義できます
# 混乱のもとなのでこのような使い方はしないようがいいです
t1.i = 10
print(t1.i) # 10 obj.nameを優先して取得します。t1からはクラス変数iを参照できません
print(Test.i) # 3
print(t2.i) # 3
# 動的な変数追加
t1.x = 10 # 動的にインスタンス変数を追加できます。
print(t1.x) # 10
del t1.x # 削除します
Test.x = 20 # 動的にクラス変数を追加できます。
print(Test.x) # 20
del Test.x # 削除します
# メソッドを呼び出します
t1.method()
#t1.__method() # エラー
# クラスメソッド呼び出し
Test.cls_meth()
# スタティックメソッド呼び出し
Test.stat_meth()
継承
クラス定義でclass Child(Parent)
と記述することで
Parentを継承するChildクラスが定義できます。
子クラスから親クラスのプライベートメンバにはアクセスできません。
親クラスのメソッドを子クラスからオーバーライドできます。
親クラスのインスタンス変数を定義するには、子クラスのコンストラクタで
親クラスのコンストラクタを呼び出す必要があります。
# 親クラスを定義します
class Parent:
i = "pub class var"
__i = "prv class var"
def __init__(self):
self.j = "pub inst var"
self.__j = "prv inst var"
def meth(self):
print("pub inst meth")
print(self.i)
print(self.__i)
self.__meth()
def meth2(self):
print("pub inst meth2")
print(self.j)
print(self.__j)
def meth3(self):
print("pub inst meth3")
def __meth(self):
print("prv inst meth")
# 子クラスを定義します
class Child(Parent):
def __init__(self):
# 親クラスのコンストラクタを呼びます
# これをなくすと親クラスのインスタンス変数が定義されません
# 子クラスからのmeth2がエラーになります
Parent.__init__(self)
# overrideします
def meth3(self):
print("child pub inst meth3")
def meth4(self):
self.__meth()
# インスタンスを作成します
p = Parent()
p.meth()
p.meth2()
p.meth3()
c = Child()
c.meth()
c.meth2()
c.meth3() # 子クラスのmeth3が呼ばれます
#c.meth4()
# エラーになります
# 子クラスから親クラスのプライベートメソッドにはアクセスできません
例外
try:
int("xxx") # 数値でないため例外発生
except OSError:
print("OSError")
except ValueError:
print("ValueError")
# resutl : ValueError
# 例外なしの場合はelseが実行されます
try:
int("10")
except OSError:
print("OSError")
except ValueError:
print("ValueError")
else:
print("NoError")
# resutl : NoError
# 例外があってもなくてもfinallyが実行されます
try:
int("xxx")
except OSError:
print("OSError")
except ValueError:
print("ValueError")
finally:
print("Finally")
# resutl : ValueError Finally
ファイル
# withを使うと例外が発生しても正しくcloseできます
with open("tmp.txt", "a") as f:
f.write("test\n")
# for文を使うとすべての行に対して処理できます
with open("tmp.txt", "r") as f:
for ln in f:
print(ln)
コマンドライン引数
コマンドライン引数はsys.argvに入ります。
sys.argv[0]はスクリプト名です。
sys.argv[1]が第1引数となります。
import sys
print(sys.argv)
>python test.py param1 param2
['test.py', 'param1', 'param2']
正規表現
import re
ln = "<tag>1234</tag>"
# 正規表現を定義します。()でグルーピングできます。
r = re.compile("<tag>(.+)</tag>")
# 検索します。
m = r.search(ln)
# マッチしなければmはNoneになります
print(m.group(0)) # マッチした文字列全体です "<tag>1234</tag>"
print(m.group(1)) # ()でグルーピングした文字列が返ります。 "1234"