2014/11/28

Python Tips:リテラルが if 文で評価されたときの結果を調べたい

Pythonで、各種リテラルが if 文で評価されたときの結果を調べる方法をご紹介します。

結論としては bool 関数を使う形がよいかと思います。

例を見てみます。
# 数値型
print bool(5)  # => True
print bool(0)  # => False
# 文字列型
print bool("Ciao")  # => True
print bool("")  # => False
# リスト型
print bool(["", ""])  # => True
print bool([])  # => False
# 辞書型
print bool({None: False})  # => True
print bool({})  # => False

最後にもうひとつ None を見てみます。
# None
print bool(None)  # => False


デバッグするときなんかに覚えておくと便利かもしれません。

以上です。

2014/11/25

サンプルコード:what_methods in Python

サンプルコード「what_methods」をご紹介します。

from what_methods_python import what

Ruby に「what_methods」というインスペクト用のライブラリがあります。指定したオブジェクトのメソッドのうち、期待した戻り値を返すメソッドだけをリストアップする what? メソッドを提供するライブラリです。

BMorearty/what_methods - GitHub


これがなかなかおもしろくてすてきなので、今回はそのPythonバージョンを作ってみました。

使い方を先に見た方がわかりやすいかと思いますので、まずは使い方から。


使い方

使うのは what 関数ひとつです。

第1引数にオブジェクト、第2引数に期待する結果を渡せば、条件を満たすメソッドをリストに格納して返してくれます。

たとえばこんな感じ。
from what_methods_python import what

print what("hello", 5)
# => ['__len__']
# 文字列 "hello" のメソッドのうち、戻り値が 5 と等しいものを調べています。
# 該当するものとして __len__ メソッドが返されました。

print what(3.14, 3)
# => ['__int__', '__long__', '__trunc__']
# 3.14 という数値のメソッドのうち、戻り値が 3 と等しいものを調べています。
# 該当するものとして複数のメソッドが返されました。
# ちなみに、戻り値の等価チェックは == で行っているため、 long なんかも含まれてきます。

メソッドに渡したい引数は、第3引数以降で指定することができます。
print what(["cat", "dog", "elephant"], "dog", 1)
# => ['__getitem__', 'pop']
# メソッドに渡す引数として 1 を指定しています。
# 該当するものとして __getitem__ pop のふたつが返ってきました。

ちなみに、 __len__ や __getitem__ のようにアンダースコア2つが先頭と末尾に付けられたメソッドはいわゆる特殊メソッドです。

直接呼び出すためではなく、何らか別の使い方をするために作られています。たとえば、 __len__ は len() 関数、 __getitem__ はアクセサ [] に相当します。


使い方はひととおりこんな感じです。あとは関数の中身を見てみます。

関数宣言

少し長いので、スクリプトまるごと Gist の方に置きました。



他から import するのではなく直接実行したらテストが走るようになっています。

以上です。

Python 版 what_methods のお話でした。


参考
BMorearty/what_methods
what_methods_python.py - Gist

2014/11/18

Python Tips:ライブラリをまとめてアンインストールしたい

Pythonでインストール済みのライブラリをまとめてアンインストールする方法をご紹介します。

アンインストールの大きな流れとしては次のとおりとなります。
  1. インストール済みのライブラリをリストアップ
  2. リストを編集
  3. pip uninstall コマンドでアンインストール


以下、順に見ていきます。


インストール済みのライブラリをリストアップ

まずは、どんなライブラリがインストールされているのかチェックします。
$ pip freeze > requirements_bk.txt
$ cp requirements_bk.txt uninstall.txt

もしものときのために復元用をバックアップしておくのがよいでしょう。 requirements_bk.txt は復元用、 uninstall.txt はアンインストール用です。


リストを編集

uninstall.txt を編集し、「削除したいライブラリ」のみの一覧を作成します。削除したいライブラリはリストに残し、残しておきたいものはリストから削除します。

たとえば次のような感じにします。

cssselect==0.9.1
lxml==3.2.4
pyquery==1.2.8


リストの編集が終わったら、あとはpipコマンドを打ち込むだけです。


pip uninstall コマンドでアンインストール

pip uninstall コマンドに r オプションを渡して先ほどの uninstall.txt をしています。
$ pip uninstall -r uninstall.txt

コマンドを実行すると、ライブラリごとに「本当に削除しますか?」という確認ダイアログが(英語で)出るので、本当によければ y を入力していきます。

確認ダイアログが必要ない場合は、 y オプションをつけることで確認なくすべてのライブラリをアンインストールすることができます。
$ pip uninstall -r uninstall.txt -y

万が一何かがあったときや改めてインストールし直したいときは、復元用の requirements_bk.txt を使って
$ pip install -r requirements_bk.txt
で元に戻しましょう。


以上です。


参考
pip uninstall — pip 公式ドキュメント
python - Is there a way to uninstall multiple packages with pip? - Stack Overflow

2014/11/12

Python Tips:行列演算を扱いたい

Pythonで行列演算をする方法をご紹介します。

Pythonで行列を扱うには「 numpy 」というライブラリを使う方法が一般的です。

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


行列オブジェクトの生成

行列オブジェクトの生成は matrix 関数で行います。
import numpy as np

# 文字列から生成
m1 = np.matrix('1 2; 3 5')

# リストから生成
m1 = np.matrix([[1, 2], [3, 5]])


要素アクセス

行列の要素へのアクセスには、リストと同じ [] を使います。
m1[0, 1]  # 1行目・2列目の要素

行全体、列全体を取得することも可能です。
m1[0]     # 1行目の要素すべて
m1[0, :]  # 同上

m1[:, 0]  # 1列目の要素すべて

m1[3:5, 0:2]  # 3~4行目・1~2列目の部分行列


四則演算

基本的な四則演算は演算子で行えます。
m1 + m2  # 和
m1 - m2  # 差
m1 * m2  # 積 ただし要素同士(追記: まちがい)
m1 / m2  # 商 ただし要素同士(追記: まちがい)

かけ算と割り算については、いずれも行列の積ではなく、要素同士のかけ算・割り算になることに注意が必要です。

追記: 指摘をいただき numpy 1.13.1 で確認をしたところ、演算 m1 * m2m1 / m2 については、要素同士の演算ではなく行列としての演算が行われるようです。この投稿を書いたときの記憶が確かではないのですが、そのとき私は numpy.array (積と商が要素同士の演算になる)と numpy.matrix (積と商が行列としての演算になる)の挙動をごっちゃにして理解、記述したのではないかと思います。。。参考にしていただく方は、ご利用の前にお手元の環境で確認をしてみてください。


メソッド

各種メソッドが用意されています。最大値や平均値など、使用頻度の高そうなものはそのままの名前で用意されています。
m1.max()  # 最大値
m1.min()  # 最小値
m1.mean() # 平均値
m1.all()  # すべて True なら True それ以外は False
m1.any()  # いずれかひとつでも True なら True それ以外は False


行列の積

* 演算子が要素同士のかけ算に割り当てられているため、行列の積は別のメソッド dot を使います。
m3 = m1.dot(m2) 行列の積


その他線形代数的演算

これらの他にも各種行列演算機能が用意されています。
from numpy import linalg as la

# 転置行列
m1_transposed = la.transpose(m1)

# 逆行列
m1_inv = la.inv(m1)

# 固有値
m1_eigenvalue = la.eig(m1)


以上です。

ほんの一部ですが、 numpy の行列機能を見てみました。 numpy には行列以外の数学的機能なども豊富に用意されているので、もっと詳しく知りたい場合は公式ドキュメントをご参照ください。


参考
numpy.matrix — NumPyマニュアル

2014/11/04

ライブラリ:inspect

Pythonの「 inspect 」というライブラリをご紹介します。

import inspect

inspect は、名前のとおり「インスペクト」ーーコードの調査を行うためのライブラリです。オブジェクトの状態や関数のふるまいを調べるための関数群が豊富に用意されています。

以下、 inspect の代表的な関数をいくつか見てみます。


inspect.getmembers()

inspect.getmembers はオブジェクトのメンバ一覧を返す関数です。

組み込み関数 dir の高機能版、と考えるとよいかと思います。

dir の場合はオブジェクトのアトリビュート名だけをリストで返しますが、 getmembers はアトリビュートの名前と中身をペアにして返してくれます。

import inspect

# dir が表示するリストのうち最後の5つだけ表示
print dir("test string")[-5:]
# => ['swapcase', 'title', 'translate', 'upper', 'zfill']

# getmembers が表示するリストのうち最後の5つだけ表示
print inspect.getmembers("test string")[-5:]
# => [('swapcase', <function swapcase>),
#     ('title', <function title>),
#     ('translate', <function translate>),
#     ('upper', <function upper>),
#     ('zfill', <function zfill>)]

inspect.isfunction()

inspect.isfunction はオブジェクトが関数かどうかを判定する関数です。引数に渡されたオブジェクトが関数であれば True 、そうでなければ False を返します。

import inspect

def hello():
    print "hello"

inspect.isfunction(hello)  # => True

if inspect.isfunction(hello):
    hello()  # => hello
    # hello が関数だったときだけ呼び出し

ただし、組み込みの関数を isfunction に渡した場合には戻り値は False となります。

組み込みの関数を調べるには、別の関数 isbuiltin を使います。

また、 inspect.isfunction は数ある is__ 関数のうちのひとつです。他にも次のような関数が用意されています。

  • ismodule モジュールなら True
  • isclass クラスなら True
  • ismethod メソッドなら True
  • isfunction 関数なら True
  • isgeneratorfunction ジェネレータ関数なら True
  • isbuiltin 組み込み関数なら True
  • isroutine 組み込み関数か自作関数なら True

この他にもまだまだたくさんあるので、もっと知りたい場合は公式ドキュメントにあたってみてください。


inspect.getsource()

inspect.getsource は、関数やメソッドのソースコードを取得するための関数です。

def hello():
    print "hello"

inspect.getsource(hello)
# => u'def hello():\n    print "hello"\n'
# hello 関数のコードを表示

以上です。

inspect には、この他にもオブジェクトやインタプリタの状態、ソースコードを調べるための関数などが豊富に用意されています。

詳しくは参考ドキュメントをご参照ください。


参考
27.13. inspect — Inspect live objects — Python公式ドキュメント
pythonのソースコードを読むコツのようなもの - maeda.na@はてな
pythonのinspect で モジュールが定義されているファイル名 をゲットする! - bokuju とか tabe1hands の日記
The GITS Blog » Python introspection with the inspect module
PyMOTW: inspect - O’Reilly ONLamp Blog