2013/09/26

ライブラリ:see

Pythonの「see」というライブラリについてご紹介します。

from see import see

「see」は、標準の関数「dir」の改良版「see」関数を提供するライブラリです。

「dir」は手軽に使えてよいのですが、出力結果が見やすくないところがたまにきずです。。そんなdirの見栄え部分を改善したのがこの「see」です。

以下、使い方を見ていきます。使い方はとてもシンプルです。

from see import see

a = list()

print 'dir():'
print dir(a)
# dir():
# ['__add__', '__class__', '__contains__', '__delattr__', 
# (一部のみ)

print 'see():'
print see(a)
# see():
#     []           in           +
#     <            <=           ==
#     hash()       help()       iter()
# (一部のみ)
dirを使うと「'__add__'」といったデフォルトのメソッド名がそのまま表示されますが、seeではそれが「+」といった人が見てわかりやすい表記に変換されて出力されます。さらにseeだと結果がきれいに整形されて出てきます。
print 'see(var, ".re*"):'
print see(a, '.re*')
# see(var, ".re*"):
#     .remove()     .reverse()
seeの第2引数にワイルドカードを含む文字列を渡すと、マッチした名前だけがずらずらっと表示されます。上記の場合ですと、「re」で始まる名前のもののみが表示されています。

以上です。


インストール
pipが入っていれば
pip install see
でインストール出来ます。


参考
see()

2013/09/25

ライブラリ:PIL

Pythonの「PIL」というライブラリについてご紹介します。

from PIL import Image

「PIL」は画像データを扱うため機能をひとまとめにしたライブラリです。名前の「PIL」は「Python Imaging Library」の省略形です。

bmp、tiff、gif、jpg、pngといったメジャーなフォーマットでの読み書きにはひととおり対応しており、機能が豊富なので、「Pythonで画像処理といえばPIL」といった位置づけになっているようです。

以下、基本的な使い方をざっくりと見ていきます。

画像の読み込み

from PIL import Image

image = Image.open('lenna.png')
print image.__class__
# PIL.PngImagePlugin.PngImageFileと表示
Image.open()で画像データを読み込むことができます。PngImageFileクラスなどのインスタンスが生成されて返されるので、その後はそのインスタンスに対して処理を施していきます。

画像の表示

image.show()
show()メソッドで画像を表示することができます。OSでその画像フォーマットに関連づけられているソフトが起動します。

画像の保存

image.save('lenna_changed.png')
save()メソッドにファイル名を与えれば、画像を保存することができます。

画像のメタ情報へのアクセス

print image.filename  # lenna.pngなどと表示
print image.format, image.size, image.mode
# PNG (220, 220) RGBAなどと表示
ファイル名(ある場合のみ)や画像フォーマット、サイズやカラーモードなどのメタ情報は、各種アトリビュートの中に入っています。image.modeは「L」「RGB」「CMYK」などの値を取り、Lならグレースケール、RGBならRGB、CMYKならCMYKなどのカラーモードを意味します。

for k, v in image.info.items():
    print k, v
# たとえば以下のとおり表示
# aspect (72, 72)
# gamma 0.45455
画素のアスペクト比、ガンマ値などの情報はinfoの中に入っています。

画素データへのアクセス

画素データにアクセスするには、大きく2通りの方法があります。ひとつはgetdata()、もうひとつはgetpixel()です。

px = image.getdata()
print px[3]  # (227, 138, 125, 255)などと表示
getdata()を使うと、すべての画素データを1列にまとめて取得することができます。getdata()とは逆にデータを書き込む方はputdata()メソッドです。

image.getpixel((x, y))
getpixel()だと、1画素単位で情報を取得することができます。取得とは逆にセットする方はputpixel()で行えます。

画像の新規作成

image = Image.new("RGB", (100, 100))
image.show()  # まっさらの画像が表示される
new()メソッドにカラーモードとサイズを渡せば、画像を新規作成することができます。

画像の統計値へのアクセス

from PIL import ImageStat

stat = ImageStat.Stat(image)
print 'pixel num:', stat.count
print 'pixel sum:', stat.sum
print 'pixel mean:', stat.mean
print 'pixel variance:', stat.var
print 'pixel stddev:', stat.stddev
# それぞれRGBAの統計値がタプルに収められて返される
ImageStat.Stat()という関数を使うと、画素の統計情報をまとめて取得することができます。countは画素の総数、sumは合計、meanは平均、varやstddevは分散や標準偏差をそれぞれ格納しています。

以上です。

この他にも、回転、拡大縮小、切り取り、明るさ・コントラストの調整といったことができます。文字や図形の書き込み、ふたつの画像の重ね合わせといった少し凝った処理なんかもメソッドひとつでできたりするので、基本的な使い方をひととおり覚えておくと便利です。


インストール
pipが入っていれば
pip install PIL
でインストールできます。


参考
PIL
Python Imaging Library Handbook
Python Imaging Library (PIL) 利用ノート - プレハブ小屋
画像処理でのPythonの利用 - slideshare

2013/09/12

ライブラリ:Requests

Python の「 Requests 」というライブラリについてご紹介します。

Python Requests

import requests

Requests は「 HTTP for Humans 」のキャッチコピーのとおり、 HTTP リクエストを人間が直感的に行えるように作られたライブラリです。インタフェースが洗練されており、かんたん・シンプルに使えるのが特徴です。

GitHub では 5,000 以上もの Star がつけられており、 Python 用のライブラリとしては Django や Flask に並ぶ最も人気の高いもののひとつかと思います。「 Python の好きなライブラリは?」という質問に対してこの Requests をあげる人も多いようです。

Python の HTTP リクエスト用のライブラリとしては、 Requests が作られる前から urllibhttplib などが存在したのですが、使い方がいまいちわかりづらい、とのことからこの Requests ライブラリが生み出されたようです。

以下、 Requests の基本的な使い方を見ていきます。

インストール


pip が入っていれば pip コマンドでそのままインストールが可能です。

pip install requests


GETリクエスト


import requests

r = requests.get('http://docs.python-requests.org/en/latest/')
print r.status_code  # 200
print r.headers  # ヘッダ情報を辞書型として格納
print r.encoding  # ISO-8859-1
GET リクエストは requests.get() という関数で行えます。 HTTP レスポンスの情報を格納した独自の Response オブジェクトが返ってくるので、その変数のアトリビュートやメソッドにアクセスする形で結果を利用することができます。

Response オブジェクトのアトリビュートのうち、 status_code はステータスコードを、 headers はヘッダ情報を、 encoding は文字コードを格納しています。

レスポンスボディの取得


r = requests.get('http://docs.python-requests.org/en/latest/')
print r.text
print type(r.text).__name__  # unicode

Response オブジェクトの text にはレスポンスのボディ部分が格納されています。ボディは自動的に unicode 化されているので、上述の encoding というのは unicode 化前の原文の文字コードを表します。

bytes データとしてのボディの取得


r = requests.get('http://docs.python-requests.org/en/latest/')
print r.content
print type(r.content).__name  # str

Response オブジェクトの content アトリビュートには、レスポンスボディの bytes 形式でのデータが格納されています。

JSON 形式でのボディの取得


r = requests.get('http://www.lifewithpython.com/feeds/posts/default?alt=json')
print r.json()
print type(r.json()).__name__  # listもしくはdict

JSON を返す URL にアクセスしたときの Response オブジェクトで json() メソッドを呼び出すと、 JSON データを parse
したものを返してくれます。データ型は通常の list 型あるいは dict 型となります。

POST/PUT/DELETE リクエスト


r = requests.post(URL_TO_POST)
r = requests.put(URL_TO_PUT)
r = requests.delete(URL_TO_DELETE)
r = requests.head(URL_TO_HEAD)
r = requests.options(URL_TO_CHECK_REQUEST_OPTIONS)

GET 以外の POST/PUT/DELETE/HEAD などのリクエストは、それぞれその名前の関数で行うことができます。直感的!

GETリクエストクエリの設定


payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get("http://httpbin.org/get", params=payload)
print r.url  # u'http://httpbin.org/get?key2=value2&key1=value1'

GET リクエストのクエリを指定したい場合は get() 関数の呼び出し時に「 params 」引数に dict を渡します。最終的にどのような
URL が生成されているかは url アトリビュートで確認することができます。

POST リクエストデータの設定


payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.post("http://httpbin.org/post", data=payload)

POST リクエストの際の送信データの指定には post() 関数の引数「 data 」を使用します。こちらも GET クエリの場合と同じく dict を渡します。

以上です。




ここでご紹介したもの以外にもさまざまな機能が用意されていて、高機能でかつわかりやすい、とても pythonic なライブラリとなっています。より詳しく知りたい方は公式のドキュメントをご覧になってみてください。

Requests に興味のある方には次のページも参考になるかもしれません。

Python Tips:Requests ライブラリのレスポンスボディの文字化けを解消したい


参考
Requests: HTTP for Humans
Requests - github

2013/09/07

ライブラリ:PyQuery

Pythonの「PyQuery」というライブラリについてご紹介します。

from pyquery import PyQuery

「PyQuery」はその名前のとおり、「Python + jQuery」なライブラリ。jQueryのような機能をPython上で提供してくれます。

「$('.myclass')」といったあのシンプルでわかりやすいAPIをPython上でも同じように使うことができます。

以下、基本的な使い方を見ていきます。まずはインスタンスの生成から。

01 PyQueryインスタンスの生成

from lxml import etree
from pyquery import PyQuery as pq

d1 = pq("<div>")
print d1  # <div/>
print type(d1)  # <class 'pyquery.pyquery.PyQuery'>
PyQueryの利用は、PyQueryクラスのインスタンス生成から始まります。「$(タグ名)」でタグ名によって生成することができます。

e = etree.Element("body")
d2 = pq(e)
print d2  # <body/>
lxml.etreeのElementインスタンスから生成することもできます。

d3 = pq(url='http://google.co.jp/')
print d3  # 指定したページのソースが表示される
URLをもとに生成することなんかもできます。

さらに、「filename」キーワードを使えば、ローカルのHTMLファイルから生成することもできるようです。このあたりの詳しいところは、ソースの該当部分をごらんいただくのがよいかと思います。

02 オブジェクトの操作: 子要素の追加

d2.append(d1)
print d2  # d2の子としてd1が追加される
append()やprepend()を使うと、PyQueryインスタンスに子要素を追加することができます。

d2.prepend(pq('<header/&;gt'))    # d2の子の先頭にheaderが追加される
d2.append(pq('<div>'))  # d2の子の末尾にdivが追加される
d2.append(pq('<footer/&gt'))  d2のこの末尾にfooterが追加される
print d2
# 以下のとおり表示
# <body><header/><div/><div/><footer/></body>

02 オブジェクトの操作: 子要素の取得

for ele in d2.children():
    print ele.tag
# 以下のとおり表示
# header
# div
# div
# footer
要素の子要素はchildren()メソッドで取得することができます。

02 オブジェクトの操作: 子孫要素へのアクセス/内容の編集

d2('div').addClass('article')
d2('.article').text('--- in div ---')
jQueryの「$( )」での要素検索と同じことが、PyQuery上でもできます。$('abc')は要素abcを、%('.abc')はクラスabcを探してきます。

d2('header').addClass('headerA')
d2('.headerA').html('archive')
addClass()、text()、html()といった、jQueryでお馴染みの便利なメソッド群も使うことができます。

02 オブジェクトの操作: CSS属性の編集

d2.attr('color', '#222')
print d2
# 以下のとおり表示
# <body color="#222"><header class="headerA">archive</header>
タグ属性の変更もjQueryと同じ形でできます。

以上です。

厳密にjQueryと同じインタフェースが実現されているわけではありませんが、大方似たような感覚で使えます。jQueryをすでによく知って使っている方にとっては、とっつきやすいライブラリのひとつではないかと思います。


インストール
pipがある場合はpipを使うのがよいかと思います。
pip install pyquery

PyQueryの利用には「lxml」というライブラリも必要となりますので、それが入っていなければ事前にインストールしておきましょう。ちなみにlxmlのインストールにはCコンパイラなどが必要とのことで、Windows環境の場合なんかにはpipよりも実行形式のインストーラを使うのがおすすめです。


参考
PyQuery
PyQuery - PyPI

2013/09/03

ライブラリ:lxml.etree

Pythonの「lxml.etree」というライブラリについてご紹介します。

import lxml.etree

「lxml.etree」は、XML形式のデータをPythonで手軽に扱えるようにするためのライブラリです。XML形式のデータがカンタンに扱えるさまざまな機能を備えています。

私は、jQueryと同等の機能を提供する「PyQuery」というライブラリを使うのに必要だったので入れました。

以下、etreeの基礎的な使い方を見ていきます。

01 インスタンスの作成

etreeの基本となるのは「Element」と呼ばれるクラスです。
from lxml import etree

root = etree.Element("root")
print type(root).__name__  # _Elementと表示
print root.tag
Element()に文字列を渡せば、その名前のElementインスタンスを作ることができます。

その要素のタグには、「tag」というアトリビュートでアクセスできます。

02 子要素の追加

child1 = etree.SubElement(root, "child1")
root.append(etree.Element("child2"))
root.insert(0, etree.Element("child3"))
print etree.tostring(root, pretty_print=True)
# 次のとおり表示
# <root>
#   <child3/>
#   <child1/>
#   <child2/>
# </root>
子要素を追加するには、SubElement()、append()、insert()といったメソッドを使います。SubElementはインスタンス生成時に親を特定して作るもので、append()とinsert()は、親要素のメソッドとして呼び出し、子要素を引数に受け取るカタチで使います。

append()とinsert()は、list型のメソッドと同じ使い方で使うことができます。

特定の要素を子要素も含めて整形して表示するには、etree.tostring()を使います。

03 テキストとコメント要素

child4 = etree.SubElement(root, "child4")
child4.text = "this is text"
root.append(etree.Comment("comment part"))
print etree.tostring(root, pretty_print=True)
# 次のとおり表示
# <root>
#   <child3/>
#   <child1/>
#   <child2/>
#   <child4>this is text</child4>
#   <!--comment part-->
# </root>
要素内のテキストには、textアトリビュートを使ってアクセスすることができます。また、コメント要素を表すクラスとしてCommentというものがあります。こちらもElementと同じようにほかの要素の子要素とすることができます。

04 子要素へのアクセス

print root[0].tag  # 
print len(root)  # 5
print root.index(root[2])  # 2
特定の要素の子要素には、インデックスを使ってアクセスすることができます。

children = list(root)
for c in children:
    print c.tag
# 次のとおり表示
# child3
# child1
# child2
# child
また、Elementを関数list()に渡すとその子要素のリストを作ることができます。

05 属性値へのアクセス

root.set("hello", "world")
root.set("dog", "taro")
a = root.attrib
print a  # {'hello': 'world', 'dog': 'taro'}
print a.get("dog")  # taro
属性値には、set()、get()などを使ってアクセスすることができます。また、属性値のセットを辞書として取得するにはattribアトリビュートを使います。

06 要素間の移動

print root[1].getnext().tag  # child2
print root[1].getprevious().tag  # child3
print root == root[1].getparent()  # True
要素間の移動をするためのメソッドとしては、getnext()、getprevious()、getparent()などが用意されています。


以上です。


インストール
ソースからインストールする場合は、pipやGithubでインストールするようです。

私は主にWindowsで使っているのですが、Windowsの場合はコンパイラの設定などがややこしいので、有志で作られているインストーラを使いました。Windowsはこちらが手早いかと思います。
lxml 2.3 - PyPI
lxml - Unofficial Windows Binaries for Python Extension Packages


etreeのほかにも、lxmlにはさまざまな便利なサブモジュールがあるようですので、詳しくは公式ドキュメントをごらんください。


参考
lxml - XML and HTML with Python
lxml - PyPI
lxml 2.3 - PyPI
lxml - Unofficial Windows Binaries for Python Extension Packages