こちらのサイトのクローンです。
以前、非常に有用な Python 入門サイトがあったのですが、しばらくしたら、サイトが削除されており、非常に残念な思いをしたことがありました。なので、個人保管用として、保存しております。
このサイトは、私個人が、自宅と、会社で同じ情報を閲覧することを目的とし、WWWに公開しています。
他言語で作業している同僚プログラマに自分が Python で記述したプログラムを
引き継いでもらうための手ほどきを主な目的とする。
プログラムについての理解はあるものとし、 Python 独特の部分を中心に解説する。
筆者の主観で考えて、一般的にあまり問題にならないであろう細かい点については言及しない。
今すぐ使えて楽に整形できるエディタとしてはてなダイアリーがあったので利用する。
http://www.python.jp/Zope/download/pythoncore の Windows 用インストーラ(msi)を実行してインストール。
最新のもので OK だが目的によってはバージョン 2.5, 2.4 が対応していないこともあるので注意。
拡張子 py, pyw を python.exe に関連付けしてくれるので以後はスクリプトをダブルクリックしたり、
コマンドプロンプトからスクリプトファイル名を入力するとそのまま実行される。
Python の基本はユニコードである。しかし現在扱っているテキストはまだ Shift JIS が多い。
Python のコード中に日本語文字列を記述するときには先頭に以下の1行を置いておく。
# coding: shift_jis
Windows で作業する場合はこの行が必ずファイルの先頭行に来るようにする。
ファイル内容を解説したコメントなどを数行置いてその下に記述するというようなことは出来ない。
以下は悪い例。
#======================================================== # hoge.py by uyamae # This is simple sample of Python script. #======================================================== # coding: shift_jis
行の中の半角の # 以降はコメントとなる。
コメントにだけ日本語を使う場合でも前述の # coding: shift_jis は必須である。
Python は、文の終わりのセミコロンが不要。ただし、セミコロンをつけてもかまわない。
基本的に1行がひとつの文となる。セミコロンをつけると1行に二つ以上の文を置くことが出来る。
逆に、行の最後に半角の \ をおくと改行が無視され複数の行にわたってひとつの文を置くことが出来る。
print "a" print "b"; print "c"; print "d" print "e" \ +"f"
コマンドラインから python.exe を実行するとインタラクティブモードで起動する。
>>> というプロンプトから直接 Python の文を入力して結果を表示できる。
複数行にわたると python.exe が解釈した場合、二行目以降ではプロンプトが ... に変わる。
インタラクティブモードを終了する場合は >>> のプロンプトで Ctrl+Z を入力して Enter.
C:\python>python Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> print 0 0 >>> print """test ... string""" test string >>> ^Z C:\python>
Python でクラスや関数の使い方が分からない場合は属性*1を表示する dir が使える。 dir は変数にも使える。
関数の使い方を知りたい場合には help が使える。
>>> f=open("sample.txt")
>>> dir(f)
['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__getattribute__', '__hash__', '__init__',
'__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'close', 'closed',
'encoding', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline',
'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines']
>>> help(f.write)
Help on built-in function write:
write(...)
write(str) -> None. Write string str to file.
Note that due to buffering, flush() or close() may be needed before
the file on disk reflects the data written.
>>>
Python で文字列を作成する場合にはシングルクォート、ダブルクォート、または三連クォートで文字列をくくる。
三連クォートの文字列は、改行を含むことが出来る。三連クォートに使うのはシングルクォートでもダブルクォートでもかまわないが当然対になっている必要がある。
print 'single quat' print "double quat" print """triple quat"""
single quat double quat triple quat
※補足 Python の print は末尾に改行を付与する。改行したくない場合は文字列の後にカンマをつける。
print 'text 1' print 'text 2\n' print 'text 3', print 'text 4'
text 1 text 2 text 3 text 4
Perl とは違ってシングルクォートとダブルクォートに違いは無く、シングルクォート中でも半角 \ によるエスケープは有効*2。
Perl のシングルクォートの文字列に相当する(エスケープを無視する)ものとして、半角 r を文字列に付与する方法がある。
この方法はシングルクォート、ダブルクォート、そして三連クォートでも有効である。
print 'single\tquat' print "double\tquat" print """triple\tdouble quat""" print r'single\tquat' print r"double\tquat" print r"""triple\tdouble quat"""
single quat double quat triple double quat single\tquat double\tquat triple\tdouble quat
Python で C の printf 相当のことをする場合には、文字列フォーマットを使用する。
利用できる書式変換は C とだいたい同じである*3。
文字列フォーマットの構文は printf とは異なる。以下の C のコードと Python のコードが同じ文字列を出力する。
printf("%d %u %.1f %s\n", 1, 2, 3, "ダー");
print "%d %u %.1f %s" % (1, 2, 3, "ダー")
Python の文字列は、加算と乗算が可能*4。加算は文字列の連結、乗算は文字列を繰り返して連結する。
Python で配列と呼べそうなものにはリストとタプルの2つがある。
リストは1次元の可変長配列として扱える。しかし、自動的に拡張はしない。
リストを作成するときは、要素をカンマで区切り [ ] でくくる。
それぞれの要素に型はなく、リストの要素としてリストを含むことも出来る。
a=[0, 'a', [1, 'b']] print a[0] print a[1] print a[2] print a[2][0] print a[2][1]
0 a [1, 'b'] 1 b
タプルもリストとだいたい同じだが、要素が変更できない。タプルは要素をカンマで区切り ( ) でくくる。
a=[0, 'a', [1, 'b']] a[1]='b' # OK t=(0, 'a', [1, 'b']) b[1]='b' # エラー b[2][0]=0 # これは OK
リスト、タプルの要素数を知るためには組み込み関数 len を使用する。
>>> a=[0, 'a', [1, 'b']] >>> print len(a) 3
リスト、タプルの添え字は 0 から始まる。また、負の数も利用できる。
負の数を指定した場合、末尾から数えてアクセスできる。-1 を指定すると一番最後の要素にアクセスできる。
>>> a[0, 'a', [1, 'b']] >>> print a[-1] [1, 'b']
リスト、タプルの一部を取り出すために、スライスが利用できる。
スライスの構文は、リスト、タプルの添え字の部分にコロンで区切った二つの値を指定する形になる。
コロンの前の数字はスライスに含まれる範囲の先頭インデックスである。
コロンの後ろの数字はスライスに含まれる範囲の最後の要素の次のインデックスである。
>>> a=[0, 1, 2, 3, 4] >>> a[1:4] [1, 2, 3] >>> a[-1:-4] [] >>> a[-4:-1] [1, 2, 3]
二つの値はそれぞれ省略可能で、前の値を省略すると 0 として扱われ、
後ろの値を省略すると指定の位置より後ろ全てがスライスの範囲に含まれる。
>>> a[:3] [0, 1, 2] >>> a[3:] [3, 4] >>> a[-1:] [4] >>> a[:-1] [0, 1, 2, 3] >>> a[:] [0, 1, 2, 3, 4]
スライスでは、リストからは新たなリスト、タプルからは新たなタプルが得られる。
それぞれはもとの配列のある範囲を要素とした新たなオブジェクトになる。
つまりリストからスライスされた新たなリストを変更しても元のリストは影響を受けない。
文字列もリストと同じような要素アクセスができる。
たとえば以下のようにして部分文字列を作ることが出来る
>>> s="test string" >>> print s[-5:] tring
文字列オブジェクト[開始インデックス:終了インデックス]
str = "ABCDE" slice = str[1:3] # "BC"
辞書は、文字列など*5を添え字とした配列のようなものである。
辞書の添え字をキーと呼ぶ。辞書を作成するときには、キーと値をコロンで対応付けた要素を
カンマで区切ってならべて { } でくくる。
辞書は代入操作では自動的に拡張されるが、値を参照するだけの場合は自動的に拡張されない。
d={'one':1, 'two':2, 'three':3}
print d['one'] # 1 が表示される
d['four']=4 # キー'four'とそれに対応する値 4 が辞書に追加される
print d['five'] # エラー
辞書にあるキーが存在するかどうかを調べたい場合には、関数 has_key が利用できる。
>>> d={'one':1, 'two':2, 'three':3}
>>> d.has_key('one')
True
>>> d.has_key('four')
False
また、関数 keys, values, items でそれぞれ辞書に含まれるキーのリスト、値のリスト、
キーと値の対を含むタプルのリストが得られる。
>>> d={'one':1, 'two':2, 'three':3}
>>> d.keys()
['three', 'two', 'one']
>>> d.values()
[3, 2, 1]
>>> d.items()
[('three', 3), ('two', 2), ('one', 1)]
*1: C++ のクラスのメンバ変数とメンバ関数を合わせたもの、あるいは Java のメソッドとフィールドをあわせたものと思ってください
*2:また C/C++ とは異なり 'a' は「 a という文字」ではなく「a」一文字の文字列である。
*3:筆者が今までに C と同じ感覚で使用して困ったことがない程度には同じです
*4:加算に見える書き方と乗算に見える書き方が可能というほうがより正確
C/C++ や Perl ではブロックは { } でくくるが、
Python ではインデントでブロックを決める。
同じインデントの連続した行がひとつのブロックとなる。
if cond: ret_code=1 #┬この2行が同じブロック print "ok" #┘ else: ret_code=2 #┬この2行が同じブロック print "NG" #┘
Python で一般的なインデントは半角スペース 4 つだが、
タブや任意の数の半角スペースでもかまわない。
ただし、コード中でインデントを混在させることは出来ない。
最初のインデントが半角スペース 4 つであれば、それ以降の
すべてのインデントはこれに従う必要がある。
インデントが2段ならば半角スペース 8 つ、3段ならば 12 個となる。
ブロック中には空白文字しか含まない行をはさむことが出来る。
if ret_code>0: print "ok" # ┬ if ret_code>0 のブロック if ret_code==1: # | print "ret_code is 1." # if ret_code==1 のブロック| else: # | print "ret_code is not 1." # else のブロック | # コメントをおいても空白行とみなされる # | print ret_code # ┘
Python では、if-elif-else、while、for が使える。
if の構文は以下の通り。
if 条件1: 条件1が真の場合の処理 elif 条件2: 条件2が真の場合の処理 else: すべての条件に当てはまらない場合の処理
C/C++ のように条件を ( ) でくくる必要はなく、
条件の後にコロンを付与する。
if 文の最後のブロックの終わりは、
次の行のインデントで見分ける。
if cond: print 0 # if cond のブロック print 1 # if cond のブロックではない
while の構文は以下の通り。
while 条件:
条件が真の場合に繰り返す処理
while を途中で抜けたい場合には break が使える。
for は Perl の foreach に近い。
for 変数 in イテレータ: 各変数に対する処理
リストはイテレータとして使われる機会が非常に多い。
また、辞書の各要素を処理する場合も多い。
>>> a = [0, 1, 2]
>>> for x in a:
... print x
...
0
1
2
>>> d = {"a":0, "b":1, "c":2}
>>> for v in d.values():
... print v
...
0
1
2
C/C++ の for 文のような使い方をしたい場合は、
range() を使用する。 range は 0 から始まり、
指定された数の要素を含むリストを返す*1。
>>> for x in range(3): ... print x ... 0 1 2
Python の変数は宣言の必要は無く、値を代入した時点で作成される。
if や while, for のブロック中で作成した変数には
そのブロック以降でもアクセスできる。
if True: x = 0 print x # OK y = 0 if True: y = 1 print y # 1 を出力
開くときにはモードを指定できる。省略時はテキスト読み込みモードになる。
open はファイルオブジェクトを返し、開く以外のファイル操作は
f=open("readme.txt") # テキスト読み込み
print f.readline() # 一行読み込んで表示
print f.tell() # 現在の読み込み位置を取得して表示
f.seek(0, 0) # ファイルの先頭に戻る
f.close() # ファイルを閉じる
f=open("readme.txt", "wb") # バイナリ書き込みモード
f.write("test text\n") # 文字列を書き込む
f.close() # ファイルを閉じる
Python では標準ライブラリなどをモジュールとして提供している。
モジュールを利用するためには import する。
import の形態には以下のようなものがある
import sys # sys モジュールを利用可能にする from os import path # os モジュールから path を取り込む from csv import * # csv モジュールに含まれる全てを取り込む import StringIO as sio # StringIO モジュールに sio という別名をつけて利用可能にする # 以上の import の結果以下のような利用が可能になる p=path.join("dir", "file.csv") # os.path.join に左の形式でアクセスできる r=reader(open(p)) # csv.reader にモジュール名の csv を省略してアクセスできる buf = sio.StringIO() # StringIO.StringIO に左の形式でアクセスできる sys.exit(0) # sys モジュールの関数に左の形式でアクセスできる
C++ や Java のオーバーライドと違って、(C++ で言うところの)シグネチャ*1が一致すれば
StringIO モジュールの StringIO はファイル風オブジェクトを返す。
このファイル風オブジェクトはファイルと同じインターフェースを持ち、
メモリ上にその内容を保持する。
import sys from StringIO import StringIO # 関数定義 def copy(src, dst, tmp): src=open(src) for text in src: tmp.write(text) src.close() tmp.seek(0, 0) dst=open(dst, "w") for text in tmp: dst.write(">%s"%text) dst.close() # StringIO を利用 buf=StringIO() copy(in_file, out_file1, buf) # 読み書き両用で開いたファイルを利用 buf=open(tmp_file, "w+") copy(in_file, out_file2, buf) buf.close()
というようにメモリ上に置く一時ファイルといった使い方が出来る。
また上記コードの tmp は読み書き両用で開いたファイルオブジェクトと容易に
交換が可能である。
コマンドプロンプトから実行した場合の引数は、sys モジュールのリスト argv に格納されている。
argv[0] には実行しているスクリプトファイル名が入り、 argv[1] 以降に引数が含まれる。
また、__name__ という変数にはモジュール名が含まれる。コマンドプロンプトから呼び出された
スクリプト中ではこの内容が "__main__" になり、これを利用して以下のようなコードがよく書かれる。
# coding: shift_jis # test.py # 関数定義 def func(x): print x*x # このモジュールがコマンドプロンプトから直接呼び出された場合に以下を実行 if __name__=="__main__": import sys if len(sys.argv)>1: func(int(sys.argv[1]))
>pytohn test.py 2
4
>python
>>>import test
>>>test.func(2)
4
def 関数名(引数,[引数, ...]):
定義
Python の関数の引数は通常のもののほかに、デフォルト値付き、任意引数リスト、
キーワード引数がある。通常の引数は関数呼び出しで渡された値を順に受け取る。
def sum(a, b): print "%d+%d=%d"%(a,b,a+b) sum(1, 2)
1+2=3
デフォルト値付き引数は、関数呼び出し時に省略可能で、その場合デフォルト値が使用される。
またデフォルト値付き引数は、関数呼び出し時に値の代入先引数を明示的に指定することができる。
代入先引数を明示的に指定する場合は、指定しないものより後ろにおく必要がある。
デフォルト値付き引数は、通常の引数より後ろにおく必要がある。
def func(a, b=0, c=1): print a, b, c func(0, 1, 2) # 普通に呼び出す func(1) # デフォルト値付き引数を省略 func(2, c=3) # 値の代入先引数を明示的に指定 func(1, b=2, 3) # こういう書き方は NG
0, 1, 2 1, 2, 1 2, 0, 3
任意引数リストは C の可変個引数関数のようなものだが python のリストとして
引数を受け取れるのでより扱いやすくなっている。
任意引数リストは引数の前に * (アスタリスク) をつけて宣言する。
任意引数リストは通常の引数とデフォルト値付き引数より後ろにおく必要がある。
def func(a, b=0, *c): print a, b, for x in c: print x, print "" func(0) # デフォルト値付き引数省略、任意引数リスト無し func(0, 1) # 任意引数リスト無し func(0, b=2) # 代入先を明示的に指定 func(0, 1, 2, 3) # a, b に対応する引数より後ろは任意引数リストに入る。 func(0, b=1, 2, 3) # こういう書き方はできない
0, 0 0, 1 0, 2 0, 1, 2, 3
キーワード引数は通常の引数、デフォルト値付き引数、任意引数リストより後ろにおく必要がある。
func(a, b=0, *c, **d): print a, b, for x in c: print x, for k, v in d.items(): print k, v, print "" func(0) # 省略できる部分を全て省略 func(0, 1, 2, 3, x=4, y=5) # 2, 3 が任意引数リストに、x=4, y=5 がキーワード引数の辞書に入る。 func(0, 1, 2, 3, x=4, 5) # キーワード引数のあとに明示的な指定の無い引数は渡せない。 func(0, 1, 2, 3, a=4, b=5) # 他の引数の名前になっているものはキーワードとして使用できない。
0, 0 0, 1, 2, 3, x, 4, y, 5
Python の関数の戻り値はひとつだが、タプルを利用して複数の引数を返すような書き方もできる。
def func(a, b) return a+b, a-b, a*b, a/b a, s, m, d = func(8, 3) print a, s, m, d
11, 5, 24, 2
この場合、関数 func の return で、カンマで列挙された値がタプルとしてまとめられて
関数の戻り値となり、その戻り値は呼び出し側でカンマで列挙された変数に展開して代入される。
ジェネレータは関数と同様の形式で定義し、呼び出すことでイテレータを生成する。
具体的には、ジェネレータは内部で yield を使用している関数である。
yield は、関数の実行を一時中断して呼び出し元に値を返す。そして値が要求されたとき
続きから処理を再開する。
def add(numbers): sum = 0 for x in numbers sum += x yield sum for x in add([1,2,4,8,16]): print x
1 3 7 15 31
クラス、インスタンスは一般的なオブジェクト指向言語と同じ考え方(クラスは設計図であり、
インスタンスはそれを元に生成された個々の製品である、のような)で取り扱うことが出来る。
Python でクラスを定義するときの構文は以下の通り。
class クラス名(基本クラス):
定義
基本クラスは省略可能だが、特別に指定したいクラスが無い場合には
クラス object を指定することが推奨されている。
「定義」の部分ではメソッドやクラスのアトリビュートを定義する。
クラスのメソッドは C++ のクラスのメンバ関数に相当する。クラスのメソッドの定義は
通常の関数とほぼ同じだが、引数リストの先頭に特殊な引数 self を追加する必要がある。
self は C++ の this ポインタのようなもので、クラスメソッドに暗黙に渡され、
class Foo(object): def __init__(self, x): self.x = x def echo(self): print self.x f = Foo(0) # Foo.__init__ が呼び出される f.echo()
0
上記のように、実際にクラスのメソッドを呼び出す場合には self を渡す必要はない。
上記のコードのクラス Foo のクラスメソッド __init__ は C++ のコンストラクタのように
インスタンスが生成されるときに呼び出される。
インスタンスのアトリビュート(属性)は C++ のクラスのメンバ変数に近い。
しかし、前節のコードの __init__ に見られるように宣言は必要なく、
値*1を渡すことで自動的に生成される。
また、後から任意にアトリビュートを追加することができる。
class Foo(object): def __init__(self, x): self.x = x def echo(self): print self.x, self.y f = Foo(0) # ここで f.echo を呼び出すとエラー f.y = "abc" # 合法 f.echo()
0 abc
ただしバグの元となるのでインスタンスの外側からアトリビュートを追加することは避けたほうが良い。
クラス定義の、メソッド定義ではない場所で定義されたアトリビュートは
クラスに属するアトリビュートとなる( C++ のクラスの static メンバ変数に近い)。
このアトリビュートにはクラス名.アトリビュートでアクセスすることが出来る。
C++ の static メンバ変数と違い、クラスのメソッド内からアクセスする場合にも
クラス名を省略することは出来ない
class Foo(object): value=0 def echo(self): print Foo.value # Foo. を省略するとエラー
Python でデータベースを扱いたくて、最初は MySQL を考えたのですが
導入部で躓いてお手軽な SQLite を選択し、いじり始めたのですが、
SHOW FIELDS が出来ないようなので、結局また MySQL にチャレンジ。
前に探したときにはなぜかたどり着けなかった MySQL のパッケージを今度は
いともたやすく発見できてしまったためインストールしてぼちぼちといじっています。
検索キーワードは MySQLdb で。
指定したパスに、ファイルやディレクトリ(フォルダ)が存在するかを調べる方法です。
import os.path os.path.exists(path)例
import os.path
os.path.exists("C:\Python25")
# => True
os.path.exists("C:\Python25\python.exe")
# => True
import os.path os.path.isfile(path)例
import os.path
os.path.isfile("C:\Python25")
# => False
os.path.isfile("C:\Python25\python.exe")
# => True
import os.path os.path.isdir(path)例
import os.path
os.path.isdir("C:\Python25")
# => True
os.path.isdir("C:\Python25\python.exe")
# => False
import os curdir = os.getcwd()
import os dirpath = 'C:/TEMP' zettaipath = os.path.join(dirpath,"note.txt")