| トップ | 読書感想文 | Ukki |
Pythonメモ

型の比較

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()


Top
Index
Search on Ukki

login

Sections:
型の比較
ジェネレーター関数(generator function), yield文
8進数/16進数からの変換
リスト操作
リストの各要素に対し一括処理を行う
実行ユーザーの取得
辞書の操作
os.system()で使用されるPATHを変更する
Unicode/日本語
try〜finally
スタックの表示
メソッド呼び出し
時間関連
文字列
ファイル
演算
os.system()のPATHの変更
main()の書き方