FrontPage


2009/2くらいからpython始めてみました。

インデントが構文に含まれていてシンプルなコードになりますし、緩い型付けも適度に型の意識をする必要があり、教育によい言語だと感じます。標準で付属している豊富なライブラリも魅力。

外部ライブラリ

変数の扱い

list

配列。

iteratableなのでループで回せる。

>>> list=[10,20,30,40]
>>> list
[10, 20, 30, 40]
>>> for l in list:
...   print l
... 
10
20
30
40

可変型なので部分差し替えが可能。

>>> list[3]=60
>>> list
[10, 20, 30, 60]

tuple

listによく似ているが微妙に違う。

()で定義する。

>>> tuple=(10,20,30,40)
>>> tuple
(10, 20, 30, 40)

オフセットアクセスが出来るのでループとかに使える(iteratableとoffset accessibleは同義?)。

>>> for t in tuple:
...   print t
... 
10
20
30
40

値の入れ替えは出来ない。

>>> tuple[3]=60
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object does not support item assignment

dictionary

dictionary型というのがある。
http://www.python.jp/doc/release/tut/node7.html

※見るたび思うが不思議な翻訳だ…

key->valueの連想配列といえるようだ。keyは数値、文字列などが利用できるが、あとから変更可能な型は使えない(チュートリアルにはappend()で値が変化されるのでlist型は使えないと書いてある)。

>>> dic={'name':'key', 'sex':'male'}
>>> dic
{'name': 'key', 'sex': 'male'}

PHP foreach()に相当する処理を行うにはdictionaryにたいしてiteritem()メソッドを実行する。

こんなかんじ。

>>> for key, value in dic.iteritems():
...   print key, value

出力結果。

name key
sex male

べんりべんり。

モジュール(ライブラリ)

かなり多くのモジュールが同梱されている。

日付や時刻の関数までモジュール化されていて、名前空間が分かれているので覚えるのがちょっと面倒くさい。

ハッシュ

md5 hashdigestをとる

md5モジュールを読み込む。

>>> import md5

newメソッドに適当な引数を渡す。

>>> hash=md5.new('hogehoge')

16進数のダイジェストを得る。

>>> hash.hexdigest()
'329435e5e66be809a656af105f42401e'

sha hashdigestを得る

shaもあった。使い方はmd5と同様。

>>> import sha
>>> hash=sha.new('hogehoge')
>>> hash.hexdigest()
'3b2c6c10d0e78072d14e02cc4c587814d0f10f3a'

re

正規表現のモジュール。

正規表現マッチ

マッチするとオブジェクトが返ってくる。

>>> import re
>>> res=re.match(r'^SoftBank\/', 'SoftBank/1.0')
>>> res
<_sre.SRE_Match object at 0x6d058>

マッチしないとNoneが返ってくる。

>>> res=re.match(r'^SoftBank\/', 'DoCoMo/1.0')
>>> res

ignore caseするならフラグをつける。

>>> res=re.match(r'^softbank\/', 'SoftBank/1.0', re.IGNORECASE)
>>> res
<_sre.SRE_Match object at 0x6d758>

time

sleepをかます。

timeをインポート

>>> import time

sleepメソッドを叩く。単位は秒。

>>> time.sleep(1)

サンプル。

% time python -c 'import time; time.sleep(1)'
python -c 'import time; time.sleep(1)'  0.02s user 0.02s system 3% cpu 1.062 total

httplib

httplibをインポート。

>>> import httplib

接続先とメソッド、パスを指定。

>>> conn=httplib.HTTPConnection('mitsukuni.org')
>>> conn.request('GET', '/index.html')

getresponseメソッドでHTTPResponseオブジェクトを拾う。

>>> res=conn.getresponse()
>>> print res
<httplib.HTTPResponse instance at 0x37ce18>

HTTPResponseオブジェクトにはレスポンスデータが入ってる。

>>> print res.status, res.reason
200 OK

ヘッダはgetheaders()メソッドをつつくとlistで取れる。

>>> headers=res.getheaders()

ループでくるくる回して表示。

>>> for key, value in headers:
...   print key, value
... 
content-length 3568
accept-ranges bytes
vary Accept-Encoding
server Apache
last-modified Thu, 15 Jan 2009 09:53:18 GMT
date Thu, 12 Mar 2009 03:45:32 GMT
content-type text/html

レスポンスボディはread()メソッドをつつく。

>>> data=res.read()
>>> print data
<html>
<head>
<title>mitsukuni.org</title>

MySQL

基本的な使い方

mysql-python bindingを使う。

db = MySQLdb.connect(db=database, host=host, port=3306, user=user, passwd=password)
cur = db.cursor()
cur.execute('SELECT * FROM table')
rows=cur.fetchall()
for row in rows:
  print row[0], row[1]
cur.close()
db.close()

かなり低レベルのAPIをつついている印象。もうちょっとスマートなやり方は無いもんかのう。 djangoのModelクラスあたりを眺めればいいのか?

Warningを拾うには

クエリ実行時のWarningを取得するには以下のようにする。

db=MySQLdb.connect(db=database, user=user, passwd=password)
cur=db.cursor()
try:
  cur.execute('stop slave io_thread')
except Exception, e:
  # exception飛んでこない...
  print e

# 数字は0のまま... 
db.warning_count()

for str in db.show_warnings():
  # Slave already has been stoppedなどが出るはず
  print str[2]

初回、warningが発生するようなクエリを投げるとstderr/stdoutのいずれかに出力されるようだ(どっちかは調べてない)。show_warnings()では値が返ってくるのにwarning_count()でまともな値が返ってこないということは、一部未実装な機能がある?

モジュール検索パスの追加

環境変数PYTHONPATHを設定する。

PYTHONPATH以下からモジュールを探してくれる。

export PYTHONPATH=${HOME}/local/lib/python2.5:${PYTHONPATH}

スクリプト内にマルチバイト文字を書く

UTF-8の場合はスクリプトの最初に次の内容を書く。

# -*- coding: utf-8 -*-

__name__について

以下に大変よいまとめがあった。

__name__には呼び出された名前(?)が入ると思っておけばよいのかな。

コマンドラインオプションの操作

optparseパッケージを使う。

from optparse import OptionParser
parser = OptionParser()

あとでもうちょっと詳しく書く^^;

文字列操作

文字列の分割

文字列にsplit()メソッドを与えると分割できる。

>>> str ='mitsukuni,sato,male'
>>> attrib = str.split(',')
>>> print attrib
['mitsukuni', 'sato', 'male']

マルチバイトでもOK

>>> str = u'光国,佐藤,男'
>>> attrib = str.split(',')
>>> print attrib
[u'\u5149\u56fd', u'\u4f50\u85e4', u'\u7537']

あれ?

>>> print attrib[0]
光国

ちゃんと出てる。なにこれ?

改行コードのトリム

文字列のrstrip()メソッドを使う。

>>> str = 'line 1\n'
>>> print str + 'hoge'
line 1
hoge
>>> print str.rstrip('\n') + 'hoge'
line 1hoge

ファイルの一覧を得る

ディレクトリの一覧を得るのは os.listdir()を使う。.や..は含まれない。

import os
files=os.listdir('./')
for f in files:
  print f

ワイルドカード指定をするにはglobを使う。

import glob
files=glob.glob('./*.jpg')
for f in files:
  print f

シグナルハンドラ

signalモジュールを使うとシグナルハンドラの定義を作れる。

import os, sys, signal, time  
  
PIDFILE='./app.pid'  
  
# プロセス番号を拾う  
pid=str(os.getpid())  
  
# プロセスIDファイルに書く  
f=open(PIDFILE, 'w')  
f.write(pid)  
f.close()  
  
# シグナルハンドラ定義  
# プロセスIDファイルを消す処理を入れた  
def sigint_handler(signum, frame):  
  os.unlink(PIDFILE)  
  sys.exit(signum)  
  
# ハンドラを追加する  
signal.signal(signal.SIGINT, sigint_handler)  
  
# 無限ループしてpidを表示し続ける  
while True:  
  print pid  
  time.sleep(1)

シグナルハンドラから例外を飛ばすことも出来る。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os, sys, signal, time

PIDFILE='./wwwpoller.pid'

# プロセス番号を拾う
pid=str(os.getpid())

# プロセスIDファイルに書く
f=open(PIDFILE, 'w')
f.write(pid)
f.close()

# シグナルハンドラ定義
# プロセスIDファイルを消す処理を入れた
def sigint_handler(signum, frame):
  raise Exception('trap signal!')

# ハンドラを追加する
signal.signal(signal.SIGINT, sigint_handler)

# 無限ループしてpidを表示し続ける
while True:
  try:
    print pid
    time.sleep(1)
  except Exception:
    print 'catch exception'
    os.unlink(PIDFILE)
    sys.exit()
  finally:
    pass

IDE


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2011-01-28 (金) 10:24:43 (2368d)