型の比較
import types
a = 'string'
if type(a) == types.StringType:
print 'yes'
else:
print 'no'
type()で型が取得できる。typesモジュールにはシステム定義型の値が用意されている。
文字列型
unicode型あるいはstr型であるかどうかは、basestringを使うと判定できる。
a = 'hello'
b = 150
c = u'漢字'
isinstance(a, basestring) → True
isinstance(b, basestring) → False
isinstance(c, basestring) → True
basestringは、ビルトイン関数として定義されているが、呼び出したり、インスタンス化することができない。
ジェネレーター関数(generator function), yield文
generator functionを定義するときに使う。逆に関数を定義するときにyield文を使うと、その関数はgenerator functionとなる。
generator functionを呼び出すとgeneratorと呼ばれるiteratorが返される(実際の型はgenerator型)。以降の操作は、このgeneratorのメソッドを呼び出して行う。コードの実行は、yield文が現れるまで行われる。
generator functionの中身はgeneratorのnext()メソッドを呼ばれたとき実行される。つまりgenerator functionが呼ばれた時点では中身は実行されない。
yieldが呼ばれたところで、実行が止まった形になる。遅延評価の形になる。generator functionのローカル変数はその間も保たれる。
ジェネレーター関数が使われるケース
呼び出す度にフィボナッチ数を1つずつ返すような場合。
ファイルからひとかたまりのデータを読み込み、その処理が終わったらまた次のひとかたまりのデータを読み込み処理したい場合、理想的にはデータの読み込みと、そのデータの処理を切り離して書けると嬉しい。こんな場合にジェネレーター関数が役に立つ。
8進数/16進数からの変換
int('10', 8) → 8
int('0a', 16) → 10
リスト操作
リストの要素をinsert
0番目の要素の前に'new'を入れる
mylist = ['a','b','c']
mylist.insert(0, 'new')
リストの要素を消す
del a[0]
del a[2:4]
配列を初期化する
ary = 38 * [None]
なんか効率悪そう。
リストの各要素に対し一括処理を行う
map()ビルトイン関数を使う。
numbers = [1,2,3,4,5]
map(str, numbers)
→['1','2','3','4','5']
map()は、str(x)をnumbersの各要素をxとして実行し結果をリストとして生成する。
ちょっと変わった処理をしたいなら、str()の代わりにラムダ関数を使う。
numbers = [1,2,3,4,5]
map(lambda x:x+1, numbers)
→numbers = [2,3,4,5,6]
実行ユーザーの取得
uidを取得するだけなら、
import os
print os.getuid()
ユーザー名を取得するなら
import pwd, os
print pwd.getpwuid(os.getuid())[0]
辞書の操作
便利なupdateメソッド
a = {1:'A', 2:'B'}
b = {2:'C', 3:'D'}
a.update(b)
a -> {1:'A', 2:'C', 3:'D'}
os.system()で使用されるPATHを変更する
os.system()は環境変数を参照するので、環境変数PATHを変更すれば良い。
import os
os.system('echo $PATH')
os.environ['PATH'] = ''
os.sytem('echo $PATH')
Unicode/日本語
str = unicode('EUC文字列', 'japanese.euc_jp')
for c in str:
print type(c), c.encode('japanese.euc_jp')
この例では、ソースコードをEUCで書いたり、外部からのデータをEUC-JPで渡したりする場合を想定している。
変数strはunicode型の文字列で、unicode()を使って生成している。
unicode型の文字列では、漢字1文字も1文字として扱われる。出力時には、encode()メソッドを使う。ここではEUC-JPに変換して出力している。
% python gaku2.py
<type 'unicode'> E
<type 'unicode'> U
<type 'unicode'> C
<type 'unicode'> 文
<type 'unicode'> 字
<type 'unicode'> 列
unicode型だとはいっても、UTF-8なわけではない。unicode型をUTF-8で出力するには、str.encode('utf-8')としなければならない。
try〜finally
try:
statement A
finally:
statement X
statement Xは、tryの中で例外が発生した場合も、しなかった場合も実行される。
実行のタイミングは、例外がない場合はtry節処理の直後、例外が発生した場合は、
例外発生直後で、finally節を実行した後、もとの例外が再度発生させられる。
スタックの表示
import traceback
def foo(a):
print traceback.print_stack()
で一応表示できる。詳細は、Python.orgの
tracebackモジュールを参照。
メソッド呼び出し
Pythonメソッド呼び出し
時間関連
現在時刻を取得する
time.time()
-> 1037158902.56
実数で返ってくるので、丸めると良い。
now = int(time.time())
年月日や時刻を特定の形式で表示したい
time.strftime("%T", time.localtime(time.time()))
時刻を表す値を生成したい
int(time.mktime((year, month, day, 0, 0, 0, 0, 0, -1)))
mktimeは、9つの要素を持つtupleを引数に取る。デイライトセービングは無視してよければ最後の要素は-1。やはり値は実数なので丸めるのもよし。
<
文字列
文字列の置換
string.replace()を使う。
"//"を"/"にする。
import string
str = "/hello/world//from/Japan/"
newstr = string.replace(str, '//', '/')
文字列の連結
a = "hello"
b = "world"
c = a + " " + b
cは"hello world"となる。
文字列のフォーマット
first ='Gaku'
last = 'Ueda'
str = 'My name is %(first)s %(last)s.' % vars()
vars()は、現在のシンボルテーブルをdictionaryとして返す。
カッコ内の名称と変数名が関連づけられ、値割り当てができる。
クラス内であれば、vars(self)とすれば、メンバ参照ができる。
class abc:
def __init__(self):
self.member1 = "HELLO"
self.member2 = "WORLD"
def doSomething(self):
print "%(member1)s and %(member2)s" % vars(self)
行末の改行を落とす
import string
line = string.rstrip(line)
文字コードの取得
a = "hello" b = ord(a[0]) 先頭の文字は、文字列a[0]でアクセスできる。組み込み関数ord()で文字コードに変換できる。 逆に文字コードから文字を得るにはchr()を使う。 chr(b + 1)
ファイル
Windowsでファイルを一気に読み込む。
fp = open(filename, 'rb')
data = fp.read()
'r'の代わりに'rb'としていしないとWindowsでは、バイナリファイルを一気に読み込むことはできない。UNIXの場合には特に必要はない。
ファイルの末尾から128バイト読み込む
fp = open(filename, 'r')
fp.seek(-128, 2)
bytes = fp.read(128)
seekの第2引数の2は、ファイルの末尾をオフセットとする。-128でそこから128バイト戻す。
リネーム: os.rename()を使う
import os
os.rename(newname, oldname)
存在チェック: os.access()
import os
os.access('/etc/rc', os.F_OK)
標準入力から1行ずつ読み込む
import sys
while 1:
line = sys.stdin.readline()
if not line:
break
sys.stdout.write(line)
lineには改行文字も含まれる。
特定のパターンのファイル名の取得
import glob
files = glob.glob('dat/2003*')
for f in files:
print f
とすると、filesは、['dat/20030811', 'dat/2003/0812']といったような結果となる。
ファイルへの書き込み
f = open('filename', 'w')
f.write("hello\n")
f.close()
複数のプロセスから1つのファイルに書き込む
import fcntl
import sys, time
while 1:
file = open('/tmp/locktest', 'a')
fcntl.lockf(file.fileno(), fcntl.LOCK_EX)
file.write("from %s" % sys.argv[1])
time.sleep(1)
fcntl.lockf(file.fileno(), fcntl.LOCK_UN)
file.close()
演算
整数切り上げ
import math
f = 3.1415
n = int(math.ceil(f))
mathモジュールのceilメソッドで切り上げができる。結果はfloatのままなので、int()で整数化する。
os.system()のPATHの変更
os.environ['PATH'] = "/sbin:/usr/bin"
os.sytem('ifconfig')
main()の書き方
def main():
...
...
if __name__ == '__main__':
main()