Hatena::Grouppython

nelnal@python

2008-01-30

[] dist にファイルを置く場合 15:26  dist にファイルを置く場合 - nelnal@python を含むブックマーク はてなブックマーク -  dist にファイルを置く場合 - nelnal@python

PyJUG の py2exe 文書に dist 直下にファイルをコピーする方法が書かれていなかったのでメモ。

まぁ、そんだけなんだけどね・・・って話なんですが。

PyJUG py2exe の文書
http://www.python.jp/Zope/articles/tips/py2exe

dist 直下にファイルをコピーする場合にはフォルダ名文字列*1を空文字列に設定すれば良い。

本当にそれだけ。

setup(

...

data_files=[ ( "", "setup.inf" ) ],

...

)


[] UnicodeDecodeError発生 15:26  UnicodeDecodeError発生 - nelnal@python を含むブックマーク はてなブックマーク -  UnicodeDecodeError発生 - nelnal@python

py2exe を編集して実行したところ UnicodeDecodeError が発生。


Traceback が出ているので見てみたのだが

(Pythonパス)\Lib\site-packages\py2exe\build_exe.py

というわけの分からんところでエラーになってる。

そもそもデータの処理は全て終わっているようで

「作成した run.exe をコピー(同時に名前を変更)」というところでエラーになっている。


うーん・・・と

色々 setup.exe のオプションを弄ってみたのだが効果なし。

暫くするうちに

setup.exe を実行しているパスに日本語を含んでいるのがいけないのでは!?と気付いた。

で、フォルダを移して再度 setup.exe を実行。そしたら普通に通った。


つーか、分かり辛いよ。

日本語のフォルダを含むパスで python スクリプトの開発をしていた俺も悪いけど。

*1:タプルの1つ目の要素

トラックバック - http://python.g.hatena.ne.jp/nelnal_programing/20080130

2008-01-29

[] 抽象メソッドを表現する 16:00  抽象メソッドを表現する - nelnal@python を含むブックマーク はてなブックマーク -  抽象メソッドを表現する - nelnal@python

現在のところ*1Pythonではクラスのメソッドを抽象表現する手段は無い。

しかし、調べてみると代わりとなる方法が分かったのでメモ。

参照1
http://newworld.ddo.jp/turky/358
参照2
http://d.hatena.ne.jp/syou6162/20070416/1176671387

どちらの場合でもスーパークラスで何らかの例外を発生させる方法で実装している。


その1

class Abstraction:
    def method(self): abstract

class Implementation(Abstraction):
    pass

inst = Implementation()
inst.method

これを実行すると NameError が発生する。

Traceback (most recent call last):

....

NameError: global name 'abstract' is not defined


その2

「その2」は自作した例外を発生させるパターン

class ExceptionOfImplementation( Exception )

class Abstraction:
    def method(self):
        raise ExceptionOfImplementation

class Implementation( Abstraction ):
    pass

inst = Implementation()
inst.method

これで抽象メソッドの実装を行わなかった時は自作した例外を発生させることで発見できる。


問題点

例外の型を指定しない except 節があると問題が発生しづらくなる可能性がある。

*1:2008/01/29現在 Python最新安定版はVersion 2.5

トラックバック - http://python.g.hatena.ne.jp/nelnal_programing/20080129

2008-01-25

[][] Windows版とcygwin版の共存でハマる 13:31  Windows版とcygwin版の共存でハマる - nelnal@python を含むブックマーク はてなブックマーク -  Windows版とcygwin版の共存でハマる - nelnal@python

下のpy2exeでの話しだが、

py2exe モジュールを導入後にコマンドプロンプト上でスクリプトを実行した時に

import py2exe

でエラーになってしまいハマった。


IDLEなどでは import に問題が無いのだが、

コマンドプロンプト上からスクリプトを実行した時のみ

「import py2exe」が上手く動作しなかった。


で、色々と調べて分かったのだが、

環境変数 PATH に cygwin の /usr/bin のパスをしていていたことと

環境変数 PYTHONPATH を設定していなかったことが原因だった*1

その設定がされていることによってコマンドプロンプト上での

python の呼び出し優先度が「 cygwinpython for windows 」となり、

いくらやっても py2exe を import 出来なかった模様。


さっそく環境変数を設定した。

PATH
既存要素の先頭にWindowsPythonインストールパスを設定
PYTHONPATH
(WindowsPythonインストールパス)\Lib\site-packages

これで、Windows版とcygwin版のPythonが問題なく(期待通りに?)動くようになった。


[][] スクリプトをexeファイル化する 11:53  スクリプトをexeファイル化する - nelnal@python を含むブックマーク はてなブックマーク -  スクリプトをexeファイル化する - nelnal@python

スクリプトをexeファイル化する、 py2exe モジュールというものがある。

py2exe
http://www.py2exe.org/
参照
http://python.matrix.jp/modules/py2exe.html

今回は以下のファイルをexeファイル(コンソール版)化するものとする。


hello.py

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

print "hello world!"

導入

py2exe のインストーラダウンロードして、インストーラを実行するだけで良い。


動作の確認。

$ python -c "import py2exe"

上のコマンドを実行してメッセージが何も出なければOK。


一番基本的な書き方

hello.py と同じディレクトリに setup.py を作成する。

:setup.py:

from distutils.core import setup
import py2exe

setup( console=[ "hello.py" ] )

次にコンソールから上記 hello.py が置かれているディレクトリに移動し、

以下のコマンドを入力

> python setup.py py2exe

正常に動作していれば、上記ディレクトリ内に build と dist という

2つのディレクトリが出来る。

ディレクトリ dist にexeファイルが出来ているので、

それを実行してみれば良い。

> hello.exe


もう少し高度な設定

今度はもう少し高度な設定をする。

from distutils.core import setup
import py2exe

setup(
      options={ "py2exe" : {
                            "compress" : 1,
                            "optimize" : 2,
                            "bundle_files" : 2
                            }
               },
      console=[ "hello.py" ] 
      )

options内のpy2exe設定について

キーワード解説
compress添付ファイルの圧縮設定0 = off, 1 = on
optimize最適化レベル設定0 = 無圧縮, 1 = 低レベル最適化, 2, = 高レベル最適化
bundle_files添付ファイル数の設定1 = 最小, 2 = 中程度, 3 = 最大

*1:2要素のどちらが根本原因かは調べてない

トラックバック - http://python.g.hatena.ne.jp/nelnal_programing/20080125

2008-01-23

syntax highlight で悪戦苦闘 16:04 syntax highlight で悪戦苦闘 - nelnal@python を含むブックマーク はてなブックマーク - syntax highlight で悪戦苦闘 - nelnal@python

最近は Eclipse + PyDev という環境で開発しているのだが

どうにも syntax highlight が気に入らない。


で、設定も見ずに導入方法を検索したら、Colorer という Plugin があるようなので、

早速 Eclipse 経由でインストールして見た。


が、設定を呼び出すと

「現在表示されているページに無効な値が含まれています」

とのメッセージ。

再起動してみたりと色々と試したが前進せず。


で、その悪戦苦闘最中に PyDev 設定に syntax highlight 設定があることを発見。

結局意味の無い悪戦苦闘だった。はぁ。

トラックバック - http://python.g.hatena.ne.jp/nelnal_programing/20080123

2008-01-22

map関数 00:09  map関数 - nelnal@python を含むブックマーク はてなブックマーク -  map関数 - nelnal@python

map関数はリストのすべて要素に同様の処理を行う時に使います。


使い方

list = map ( function, list, ... )

function
引数をもつ関数引数の数はリストの数と合わせること。また、戻り値を持つこと。
list
1つ以上の要素をもったリスト。リストの数はfunction引数に合わせること。

戻り値
functionの実行結果をまとめてリストにして返します。

サンプルコード

def func( item ):
    print "This is a " + item + "."

map( func, [ "pen", "banana", "car" ] )


def func2( a, b, c ):
    return a ** 2 + b * c

map( func2, [1, 3, 5], [ 8, 12, 2 ], [ 5, 2, -3 ] )

ただし、上記の程度の簡単な処理なら、

for 文と zip() を使った組み合わせのほうが簡単だと思われる。


[] 等価と同一 23:54  等価と同一 - nelnal@python を含むブックマーク はてなブックマーク -  等価と同一 - nelnal@python

Pythonでは「等価」と「同一」は異なる意味となる。

等価
2つのオブジェクトを構成する要素*1が各々同じである。
同一
2つのオブジェクトはメモリ上の同じアドレスに存在するデータを参照している。

「等価」は「==」演算子を、「同一」は「is」演算子を使います。

>>>s1 = "spam"
>>> s2 = s1
>>> s1 == s2, s1 is s2
(True, True)

>>> s1 = "This is a pen."
>>> s2 = "This is a pen."
>>> s1 == s2, s1 is s2
(True, False)

ただし、文字列ではデータ長が短い場合に限り、

同一メモリアドレスのデータを参照する場合がある。

*1:ネストされているものも含む

トラックバック - http://python.g.hatena.ne.jp/nelnal_programing/20080122

2008-01-21

range と xrange 16:25 range と xrange - nelnal@python を含むブックマーク はてなブックマーク - range と xrange - nelnal@python

参照
http://d.hatena.ne.jp/tomisima/20070720/1184915006

range, xrange はそれぞれ

range -> リスト型

xrange -> xrange オブジェクト

を返す。


コメント欄にもあるが、

大きいリスト(?)を生成する時に range だとリソースの消費が激しい模様。

xrange は生成するデータサイズに関係なく一定のリソースしか使わない。


xrange は generator か?

だとすると for 文で使う限りにおいてはメリットがありそうな・・・。

で、{range|xrange}の結果を変数に入れるんならあまり変わらんと。

まぁ、でもそんな大きい値を使う予定は無いが。

トラックバック - http://python.g.hatena.ne.jp/nelnal_programing/20080121

2008-01-20

[] 文字列から文字を除去 23:41  文字列から文字を除去 - nelnal@python を含むブックマーク はてなブックマーク -  文字列から文字を除去 - nelnal@python

rstrip

rstrip は文字列右から指定文字を除去するメソッド。

string.rstrip( [ chars ] )

chars
除去したい文字の集合。文字列型で指定すること。

引数を指定しない場合は

  • \t
  • \n
  • \r
  • \v*1
  • \f*2

が除去する文字として扱われる。


サンプルコード

以下の方法は改行コード(win = \r\n, mac = \r, unix = \n)を意識せずに改行を除去して、

実行環境の改行コードで出力(標準出力)する方法。

fh = open("test.txt", "r")

lines = fh.readlines("")
for line in fh.readlines:
    print line.rstrip();

fh.close();

lstrip

lstrip は文字列左から指定文字を除去するメソッド。

string.lstrip( [ chars ] )

引数の使い方は rstrip と同様。

引数が省略された場合は空白文字が除去される。


strip

strip は文字列左右から指定文字を除去するメソッド。

string.strip( [ chars ] )

引数の使い方は rstrip, lstrip と同じ。

引数が省略された場合は空白文字が除去される。


dedent

dedent はインデントを除去するメソッド。

textwrap モジュールに含まれる。

import textwrap

ret = textwrap.dedent( string )

string
インデントを除去したい文字列
(return)
インデントを除去した文字列

サンプルコード

三重引用符のインデントを除去

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

import textwrap

def test():
    str = """\
    Hello, 
    world!""";
    print str;
    print "-" * 8;
    print textwrap.dedent( str );

if __name__ == '__main__':
    test();

[] 簡単にモジュールの有無をチェック 23:41  簡単にモジュールの有無をチェック - nelnal@python を含むブックマーク はてなブックマーク -  簡単にモジュールの有無をチェック - nelnal@python

それの転用


モジュールが存在する時

$ python -c "import sys"

$

何もメッセージが出なければ問題なし。

逆にメッセージが出るようだとモジュールインストールされてません。

さっさと Cheese Shop 等に行ってインストールしましょう。


モジュールが存在しない時

$ python -c "import tekito"

Traceback (most recent call last):

File "<string>", line 1, in ?

ImportError: No module named tekito

$

*1:0x000B : 垂直タブ。

*2:0x000C : フォームフィード。紙送り、改行のこと。

トラックバック - http://python.g.hatena.ne.jp/nelnal_programing/20080120