定数を使う
# Put in const.py...:
class _const:
class ConstError(TypeError): pass
def __setattr__(self,name,value):
if self.__dict__.has_key(name):
raise self.ConstError, "Can't rebind const(%s)"%name
self.__dict__[name]=value
import sys
sys.modules[__name__]=_const()
# that's all -- now any client-code can
import const
# and bind an attribute ONCE:
const.magic = 23
# but NOT re-bind it:
const.magic = 88 # raises const.ConstError
# you may also want to add the obvious __delattr__
乱数を使う
>>> import random
>>> random.randint(10, 20)
20
>>> random.randint(10, 20)
15
>>> random.randrange(1, 100, 0.1 ,float)
46.119009462591606
>>> random.randrange(1, 100, 0.1 ,float)
7.071109538788602
>>> random.uniform(1, 2)
1.081592539297926
>>> random.seed(1)
>>> random.uniform(1, 2)
1.1343642441124011
>>> random.seed(1)
>>> random.uniform(1, 2)
1.1343642441124011
10進数演算の結果を正しく求める
>>> import decimal
>>> dnum = decimal.Decimal("1.1")
>>> dsum = decimal.Decimal("0")
>>> rnum = 1.1
>>> rsum = 0.0
>>> for i in range(10):
... dsum = dsum + dnum
... rsum = rsum + rnum
...
>>> # 丸め誤差がでる
>>> rsum
10.999999999999998
>>> # 丸め誤差がでない
>>> dsum
Decimal("11.0")
>>> str(dsum)
'11.0'
文字コードを推測する
def guess_encoding(s):
encodings=["ascii","utf-8","shift-jis","euc-jp"]
for enc in encodings:
try:
unicode(s,enc)
break
except UnicodeDecodeError,e:
enc=""
return enc
辞書のキーを生成する
class auto_dict(dict):
def __getitem__(self, key):
return self.setdefault(key, self.__class__())
if __name__ == "__main__":
d = auto_dict()
d["foo"]["bar"]["baz"] = 42
print d
スレッドを使う
import threading
class TestThread(threading.Thread):
"""
A sample thread class
"""
def __init__(self):
"""
Constructor, setting initial variables
"""
self._stopevent = threading.Event()
self._sleepperiod = 1.0
threading.Thread.__init__(self, name="TestThread")
def run(self):
"""
overload of threading.thread.run()
main control loop
"""
print "%s starts" % (self.getName(),)
count = 0
while not self._stopevent.isSet():
count += 1
print "loop %d" % (count,)
self._stopevent.wait(self._sleepperiod)
print "%s ends" % (self.getName(),)
def join(self,timeout=None):
"""
Stop the thread
"""
self._stopevent.set()
threading.Thread.join(self, timeout)
if __name__ == "__main__":
testthread = TestThread()
testthread.start()
import time
time.sleep(10.0)
testthread.join()
テンポラリファイルを使用する
>>> import tempfile
>>> print tempfile.gettempdir()
c:\docume~1\admini~1\locals~1\temp
f=tempfile.TemporaryFile()
f.write(aaa)
CSVファイルの読み書き
import csv
# CSVファイルを読み込む
csvfile=open("test.csv");
if csvfile != None:
for row in csv.reader(csvfile):
for col in row:
print col
# CSVファイルを作る
writer = csv.writer(open('test.csv','w'))
writer.writerow(["a", "1","memo1"])
writer.writerow(["c", "2","memo2"])
del writer
# dict型を書き込む
writer = csv.DictWriter(open('test.csv','w'),['a', 'b', 'c'], lineterminator = '\n')
writer.writerows([{'a':'1', 'b':'2', 'c':'3'},{'a':4, 'b':[5,5], 'c':6}])
del writer
ZIPファイルを処理する
import zipfile
z = zipfile.ZipFile("zipfile.zip", "rb")
for filename in z.namelist():
print filename
bytes = z.read(filename)
print len(bytes)
INIファイルの読み書き
from ConfigParser import ConfigParser
# 書き込み
f = open("config.ini", "w")
parser = ConfigParser()
parser.add_section("TEST1")
parser.add_section("TEST2")
parser.set("TEST1", 'A', 'abc')
parser.set("TEST2", 'B', 3)
parser.set("TEST1", 'C', ['a', 'b', 'c'])
parser.set("TEST2", 'D', {'a':1, 'b':2, 'c':3})
parser.write(f)
# 読み込み
parser = ConfigParser()
parser.read("config.ini")
print parser.get("TEST1", 'A')
print parser.get("TEST2", 'B')
l = eval(parser.get("TEST1", 'C'))
print l[0]
d = eval(parser.get("TEST2", 'D'))
print d['a']
オブジェクトの読み書き
import pickle
data = {1:2, 2:3, 3:4}
# 書き込み
f = open(filename, "wb")
pickle.dump(data, f)
f.close()
# 読み込み
f = open(filename, "rb")
data = pickle.load(f)
f.close()
現在日時を調べる
#日付を取るにはdatetime.dateを使います。
>>> from datetime import date
>>> now = date.today()
>>> now
datetime.date(2003, 12, 2)
# 日付を書式付きで出力
>>> now.strftime("%m-%d-%y or %d%b %Y is a %A on the %d day of %B")
12-02-03 or 02Dec 2003 is a Tuesday on the 02 day of December
# 日付の差を求める
>>> birthday = date(1964, 7, 31)
>>> age = now - birthday
>>> age.days
14368
#timeモジュールで時間が取れます
>>> import time
>>> time.ctime()
Mon Feb 13 16:22:14 2006
>>> time.gmtime()
(2006, 2, 13, 7, 22, 21, 0, 44, 0)
# 1970年からの秒数です。
>>> time.time()
1139815346
# 現在時刻を取得
>>> time.strftime("%Y/%m/%d %H:%M:%S[%a]",time.localtime())
'2007/08/22 10:47:05[Wed]'
時間計測
#-----------------------------
# High Resolution Timers
t1 = time.clock()
# Do Stuff Here
t2 = time.clock()
print t2 - t1
# 2.27236813618
# Accuracy will depend on platform and OS,
# but time.clock() uses the most accurate timer it can
time.clock(); time.clock()
# 174485.51365466841
# 174485.55702610247
#-----------------------------
# Also useful;
import timeit
code = '[x for x in range(10) if x % 2 == 0]'
eval(code)
# [0, 2, 4, 6, 8]
t = timeit.Timer(code)
print "10,000 repeats of that code takes:", t.timeit(10000), "seconds"
print "1,000,000 repeats of that code takes:", t.timeit(), "seconds"
# 10,000 repeats of that code takes: 0.128238644856 seconds
# 1,000,000 repeats of that code takes: 12.5396490336 seconds
#-----------------------------
import timeit
code = import random; l = random.sample(xrange(10000000), 1000); l.sort()
t = timeit.Timer(code)
print "Average Time:", t.timeit(1000) / 1000
# Time taken: 5.24391507859
コマンドを実行
def gethostname(ipaddress):
import os,string
cmd=('tracert -w 10 -h 1 '+address)
#print cmd
p=os.popen2(cmd)
result = p[1].read()
##print result
print string.split(result,\r\n)[1]
baseaddress=192.168.11
for i in range(10):
address=baseaddress+'.'+str(i)
#print addres
gethostname(address)
正規表現で検索
import re
reg = re.compile(r"abc")
m = reg.search("abcabcabcdedeagc")
for txt in m
if txt != None:
print txt
文字の出現頻度を調べる
a = "banana"
print a.count('a')
HTMLを処理する
import sgmllib, urllib, urlparse
class LinksParser(sgmllib.SGMLParser):
def __init__(self):
sgmllib.SGMLParser.__init__(self)
self.seen ={}
def do_a(self, attributes):
for name, value in attributes:
if name == href and value not in self.seen:
self.seen [value] = True
pieces = urlparse.urlparse(value)
if pieces[0] != http : return
print urlparse.urlunparse(pieces)
return
p = LinksParser()
f=urllib.urlopen(http://www.python.org/index.html)
BUFSIZE = 8192
while True:
data = f.read(BUFSIZE)
if not data: break
p.feed(data)
p.close()
HTMLを処理する2
#------------------------------------------------------------------------------
# import
#------------------------------------------------------------------------------
from HTMLParser import HTMLParser
import urllib2
#------------------------------------------------------------------------------
# クラス定義
#------------------------------------------------------------------------------
class TestHtmlParser(HTMLParser):
"""
HTMLParserテスト用
"""
def handle_starttag(self, tag, attrs):
print "[starttag]", tag, attrs
def handle_startendtag(self, tag, attrs) :
print "[startendtag]", tag, attrs
def handle_endtag(self, tag):
print "[endtag]", tag
def handle_data(self, data):
print "[data]", data
def handle_charref(self, ref):
print "[charref]", data
def handle_entityref(self, name):
print "[entityref]", name
def handle_comment(self, data):
print "[comment]", data
def handle_decl(self, decl):
print "[decl]", decl
def handle_pi(self, data):
print "[pi]",data
#------------------------------------------------------------------------------
# テスト関数定義
#------------------------------------------------------------------------------
def __test():
import urllib2
f =urllib2.urlopen(
r"http://www.forexite.com/free_forex_quotes/forex_history_arhiv.html")
p = TestHtmlParser()
p.feed(f.read())
#------------------------------------------------------------------------------
# main
#------------------------------------------------------------------------------
if __name__ == "__main__":
__test()
HTMLを読み込む
import urllib2
f =urllib2.urlopen(http://diveintopython.org/)
htmlSource = f.read()
print htmlSource
XSLTを読み込む
from xml.xslt.Processor import Processor
from xml.xslt.StylesheetReader import StylesheetReader
class StylesheetFromDict(StylesheetReader):
"A stylesheet reader that loads XSLT stylesheets from a python dictionary"
def __init__(self, styles, *args):
"Remember the dict we want to load the stylesheets from"
apply(StylesheetReader.__init__, (self,) + args)
self.styles = styles
self.__myargs = args
def __getinitargs__(self):
"Return init args for clone()"
return (self.styles,) + self.__myargs
def fromUri(self, uri, baseUri='', ownerDoc=None, stripElements=None):
"Load stylesheet from a dict"
parts = uri.split(':', 1)
if parts[0] == 'internal' and self.styles.has_key(parts[1]):
# load the stylesheet from the internal repository (our dict)
return StylesheetReader.fromString(self, self.styles[parts[1]],
baseUri, ownerDoc, stripElements)
else:
# revert to normal behaviour
return StylesheetReader.fromUri(self, uri,
baseUri, ownerDoc, stripElements)
if __name__ == "__main__":
# the sample stylesheet repository
internal_stylesheets = {
'second-author.xsl': """
<person xmlns:xsl="http://www.w3.org/1999/XSL/Transform" \
xsl:version="1.0">
<xsl:value-of select="books/book/author[2]"/>
</person>
"""
}
# the sample document, referring to an "internal" stylesheet
xmldoc =
"""
<?xml-stylesheet href="internal:second-author.xsl" \
type="text/xml"?>
<books>
<book title="Python Essential Reference">
<author>David M. Beazley</author>
<author>Guido van Rossum</author>
</book>
</books>
"""
# create XSLT processor and run it
processor = Processor()
processor.setStylesheetReader(StylesheetFromDict(internal_stylesheets))
print processor.runString(xmldoc)
ftpクライアント
import ftplib
ftp = ftplib.FTP("ftp.host.com")
ftp.login(username, password)
ftp.cwd(directory)
# get file
outfile = open(filename, "wb")
ftp.retrbinary("RETR %s" % filename, outfile.write)
outfile.close()
# upload file
upfile = open(upfilename, "rb")
ftp.storbinary("STOR %s" % upfilename, upfile)
upfile.close()
ftp.quit()
SMTPでメール送信
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email.Header import Header
from email import Encoders
import os
def sendMail(to, subject, text, files=[],
server="localhost",port = 25,
user='', password=''):
assert type(to)==list
assert type(files)==list
fro = "hogehoge"
msg = MIMEMultipart()
msg['From'] = fro
msg['To'] = COMMASPACE.join(to)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = Header(subject, 'ISO-2022-JP')
msg.attach( MIMEText(text.encode("mbcs",'ignore'), 'plain', 'shift-jis') )
for file in files:
part = MIMEBase(application, "octet-stream")
part.set_payload( open(file,"rb").read() )
Encoders.encode_base64(part)
part.add_header(Content-Disposition,
"attachment; filename=\"%s\"" % os.path.basename(file))
msg.attach(part)
# g-mail向け送信処理
smtp = smtplib.SMTP(server, port)
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login(user, password)
smtp.sendmail(fro, to, msg.as_string() )
smtp.close()
# 通常送信処理
#smtp = smtplib.SMTP(server, port)
#smtp.sendmail(fro, to, msg.as_string() )
#smtp.close()
txt = u"""
これぐらいながいのを送信しても
大丈夫だんだろうかなぁ~
ABCD EFG HIJK
---
テスト
"""
sendMail(["aaaaaaaaaaaaa@aaaaaaaaaaaaa.ne.jp"],
u"送信テスト",
txt,
server="smtp.mail.seaver",
port = 1000,
user="username",
password="password"
)
ファイルをダウンロードする
def __download(url , savename =''):
"""
ファイルをダウンロードする
"""
# 処理途中で終了した場合に不完全なファイルができるの限り防ぐために、
# ダウンロードをしたデータは一時ファイルに保存する。
# ダウンロード後ファイル名を変更する。
tmpname = r'xhofile.tmp'
webfile = urllib2.urlopen(url)
tmpfile = open(tmpname,'wb')
tmpfile.write(webfile.read())
webfile.close()
tmpfile.close()
# 名前を変更する
if savename == '':
savename = url.split('/')[-1]
os.rename(tmpname, savename)
return savename
if __name__ == '__main__':
import sys
if len(sys.argv) == 2:
try:
download(sys.argv[1])
except IOError:
print 'Filename not found.'
else:
import os
print 'usage: %s http://server.com/path/to/filename' \
% os.path.basename(sys.argv[0])
sqliteを使う
import sqlite3
con = sqlite3.connect(db_name)
cur = con.cursor()
cur.execute("SELECT * FROM %s;" % table_name)
result = cur.fetchall()
print result
con.commit()
cur.close()
con.close()
集合を表現するための型setを使う
>>> a = set("hello world")
>>> a
set([' ', 'e', 'd', 'h', 'l', 'o', 'r', 'w'])
>>> b = set("good bye")
>>> 'w' in a
True
>>> a & b
set([' ', 'e', 'd', 'o'])
>>> a ^ b
set(['b', 'g', 'h', 'l', 'r', 'w', 'y'])
>>> a | b
set([' ', 'b', 'e', 'd', 'g', 'h', 'l', 'o', 'r', 'w', 'y'])
テンプレートを作って、文字列を出力する
>>> # 名前をベースにした文字列の置き換え機能
>>> import time
>>> msg = "Hello %(name)s , it's %(hour)i o'clock."
>>> msg % {"hour": time.localtime().tm_hour, "name": "James Random Hacker"}
"Hello James Random Hacker , it's 20 o'clock.
>>> # テンプレートを利用した文字列の置き換え機能
>>> import string
>>> msg = string.Template("Hello $name , it's $hour o'clock")
>>> msg.substitute({"name": "James Random Hacker", "hour": time.localtime().tm_hour})
"Hello James Random Hacker , it's 20 o'clock"
>>> msg.substitute({"name": "James Random Hacker", "hour": "01"})
"Hello James Random Hacker , it's 01 o'clock"
関数やメソッドを修飾する
>>> import time
>>> def createdTime(funcObj):
... funcObj.createdTime = time.time()
... return funcObj
...
>>> @createdTime
... def foo(x):
... print x + 1
...
>>> @createdTime
... def bar(name):
... print "Hello %s" % name
...
>>> # オブジェクトの生成時間がわかる
>>> foo.createdTime
1103025973.760793
>>> bar.createdTime
1103026042.8535249
>>> foo(10)
11
>>> bar("World")
Hello World
関数の引数の型をチェックする
import math
def declareArgs(*argTypes):
def checkArguments(func):
assert func.func_code.co_argcount == len(argTypes)
def wrapper(*args, **kwargs):
pos = 1
for (arg, argType) in zip(args, argTypes):
assert isinstance(arg, argType), \
"Value %r dose not match %s at %d" % (arg, argType, pos)
pos += 1
return func(*args, **kwargs)
wrapper.func_name = func.func_name
return wrapper
return checkArguments
@declareArgs(float, float)
def calcDistance(x, y):
return math.sqrt(x * x + y * y)
print calcDistance(3.14, 1.592)
# エラーになる
print calcDistance(2.0, 4)
キーコードをアプリに送信
import win32api
import win32com.client
shell = win32com.client.Dispatch("WScript.Shell")
shell.Run("calc")
win32api.Sleep(100)
shell.AppActivate("Calculator")
win32api.Sleep(100)
shell.SendKeys("1{+}")
win32api.Sleep(500)
shell.SendKeys("2")
win32api.Sleep(500)
shell.SendKeys("~") # ~ is the same as {ENTER}
win32api.Sleep(500)
shell.SendKeys("*3")
win32api.Sleep(500)
shell.SendKeys("~")
win32api.Sleep(2500)
IEを制御
import win32com.client
ie=win32com.client.Dispatch("InternetExplorer.Application")
ie.Visible=1
#指定のurlへジャンプするにはIEのNavigate()メソッドを使えばよい
ie.Navigate("http://www.msi.co.jp")
#busy中に他の制御をするとおかしくなる。
#NG:
ie.Navigate(url)
print ie.Document.body.innerHTML
ie.ExecWB(4,0)
#OK:
ie.Navigate(url)
while(ie.busy):
time.sleep(1)
print ie.Document.body.innerHTML
ie.ExecWB(4,0)
Windowsでユーザ情報を取得する
import win32api
import win32net
import win32netcon
def UserGetInfo():
dc=win32net.NetServerEnum(None,100,win32netcon.SV_TYPE_DOMAIN_CTRL)
user=win32api.GetUserName()
if dc[0]:
dcname=dc[0][0]['name']
return win32net.NetUserGetInfo("\\\\"+dcname,user,1)
else:
return win32net.NetUserGetInfo(None,user,1)
if __name__=="__main__":
print UserGetInfo()
Windowsでレジストリにアクセスする
from _winreg import *
print r"*** Reading from SOFTWARE\Microsoft\Windows\CurrentVersion\Run ***"
aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE)
aKey = OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run")
for i in range(1024):
try:
n,v,t = EnumValue(aKey,i)
print i, n, v, t
except EnvironmentError:
print "You have",i," tasks starting at logon..."
break
CloseKey(aKey)
print r"*** Writing to SOFTWARE\Microsoft\Windows\CurrentVersion\Run ***"
aKey = OpenKey(aReg,
r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
0,
KEY_WRITE)
try:
SetValueEx(aKey,"MyNewKey",0, REG_SZ, r"c:\winnt\explorer.exe")
except EnvironmentError:
print "Encountered problems writing into the Registry..."
CloseKey(aKey)
CloseKey(aReg)
Windowsのサービスを制御する
import win32serviceutil
def service_info(action, machine, service):
if action == 'stop':
win32serviceutil.StopService(service, machine)
print '%s stopped successfully' % service
elif action == 'start':
win32serviceutil.StartService(service, machine)
print '%s started successfully' % service
elif action == 'restart':
win32serviceutil.RestartService(service, machine)
print '%s restarted successfully' % service
elif action == 'status':
if win32serviceutil.QueryServiceStatus(service, machine)[1] == 4:
print "%s is running normally" % service
else:
print "%s is *not* running" % service
if __name__ == '__main__':
machine = 'cr582427-a'
service = 'Zope23'
action = 'start'
service_info(action, machine, service)
実行ファイルに変換する
# 以下の内容をsetup.pyとして保存
# python setup.py py2exeで実行ファイルができる
# setup.py
from distutils.core import setup
import glob
import py2exe
# 単純なコンソールアプリ
setup(console=["fxdata.py"])
#------------------------------------------------------------------------------
# Windowsアプリ
# setup(name="myclock",
# windows=["myclock.py"],
# )
#------------------------------------------------------------------------------
# データを持たせる場合
# setup(console=["myscript.py"],
# data_files=[("bitmaps",
# ["bm/large.gif", "bm/small.gif"]),
# ("fonts",
# glob.glob("fonts\\*.fnt"))],
# )
#------------------------------------------------------------------------------
# Windows NTサービス
# setup(service=["MyService"])
#------------------------------------------------------------------------------
# COMサーバー
# setup(com_server=["win32com.server.interp"])
pdb(デバッガ)の使い方
pdb を使ってデバッグするにはコマンドラインに以下のように入力します。
% pdb デバッグ対象のPythonスクリプト使用方法は以下のとおり
- n コマンドで ステップ実行
- s(step) コマンドでステップイン実行
- l(ist) コマンドで現在位置の前後のコードを表示
- p コマンドで変数の中身を表示
- w(where) コマンドでスタックトレースを表示
- q(uit) コマンドで終了
実行時に名前からモジュールを読み出す
test.py
class Test:
def __init__(self):
print "Test"
def run(self):
print "run"
test1.py
import test
class Test1(test.Test):
def __init__(self):
test.Test.__init__(self)
print "Test1"
def run(self):
print "run1"
test2.py
import test
class Test2(test.Test):
def __init__(self):
test.Test.__init__(self)
print "Test2"
def run(self):
print "run2"
test1.pyのTest1と,test2.pyのTest2をインポート後実行する。
引数等からモジュール名を与えれば、機能を変更できる
import test
def importName(modulename, name):
"""
モジュール(modulename)からオブジェクト(name)をインポートする
"""
try:
module = __import__(modulename, globals(), locals(), [name])
except ImportError:
return None
return vars(module)[name]
def runTest(modulename):
"""
モジュールを実行する
"""
Tester = importName(modulename.split('.')[0], modulename.split('.')[1])
tester = Tester()
tester.run()
if __name__ == "__main__":
print '-' * 80
runTest("test1.Test1")
print '-' * 80
runTest("test2.Test2")
プロファイルをとる(各関数の実行時間を計測する)
import profile
profile.run('__test()')
DLLの関数を呼び出す
import ctypes
mtc = ctypes.cdll.LoadLibrary("MTClient.dll")
print mtc
mtcStart = mtc.MTCStartAll
mtcWaitUpdate = mtc.MTCWaitUpdate
mtcStop = mtc.MTCStop
print mtcStart, mtcWaitUpdate, mtcStop
result = ctypes.c_buffer(0x100);
handle = mtcStart("USDJPY", result)
for i in range(10):
ret = mtcWaitUpdate(handle, 2)
if ret != 0:
print repr(result.value)
else:
print i, "timeout"
mtcStop(handle)