型の比較
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モジュールを参照。
メソッド呼び出し
時間関連
現在時刻を取得する
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()
