2514172 ランダム
 ホーム | 日記 | プロフィール 【フォローする】 【ログイン】

傀儡師の館.Python

PR

日記/記事の投稿

カレンダー

キーワードサーチ

▼キーワード検索

カテゴリ

バックナンバー

2020年01月
2019年12月
2019年11月
2019年10月
2019年09月
2019年08月
2019年07月
2019年06月
2019年05月
2019年04月

フリーページ

プロフィール


kugutsushi

サイド自由欄

設定されていません。
2008年04月05日
XML
カテゴリ:IronPython
『IronPython の世界』を読む (1)
の続きで、Part 3 「CPython との互換性」のあたりを読む。

p.104 の Memo に次のようにある。

辞書の定義を行うときの入力方法にも CPython との違いがあります。CPython であれば、カンマ「,」のあとで改行し、ブロックプロンプトを使って複数行で入力できます。ですが、IronPython のインタラクティブシェルでは、複数行による定義を行うことができません。

と書かれているのだが、

>>> d = {'Iron':'Python',
... 'C':'Python',
... 'p':'Programming'}
>>> d
{'Iron': 'Python', 'C': 'Python', 'p': 'Programming'}

みたいなことはできる。んー、ここでは何が言いたいのだろうか、よくわからない。

IronPython はプロンプトで、__dict__ と打つとグローバルレベルでの __dict__ オブジェクトを利用でき、CPtyhon だと import sys; sys.modules[__name__].__dict__ とかある。

これ以外にも、モジュールやクラスなどに対する「__dict__」の取り扱いが CPython と異なっています。

とある。このあたり、ちょっと不都合なことが出てきそうなのではまりどころになるかもしれない。Python の文法チェックには何を使う? lint はないの?python 用 lint、Pyflakes vs. pyChecker vs. pylint あたりのツールは意図したように動くのだろうか、要確認。そのうち調べる。

データ型については p. 109 にまとめられているが、集合型 (set) が IronPython.Runtime.SetCollection として実装されていたり、文字列型 (str) が System.String として実装されていたりで、こうしたことから、微妙に振る舞いが違うこととかが出てくるということか。IronPython には sets モジュールは存在せず、組み込み型の set だけ使える。

sets.Set が使いたければ、Pure Python だから CPython の使っちゃうかな。from sets import Set as set みたいなことをやっているものがけっこうあるから、set だけあってもだめだったりする。

CPython
>>> from sets import Set as set
>>> dir(set)
['__and__', '__as_immutable__', '__as_temporarily_immutable__',
'__class__', '__cmp__', '__contains__', '__copy__', '__deepcopy__',
'__delattr__', '__doc__', '__eq__', '__ge__', '__getattribute__',
'__getstate__', '__gt__', '__hash__', '__iand__', '__init__',
'__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__',
'__lt__', '__module__', '__ne__', '__new__', '__or__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__slots__',
'__str__', '__sub__', '__xor__', '_binary_sanity_check',
_compute_hash', '_data', '_repr', '_update', 'add', 'clear', 'copy',
'difference', 'difference_update', 'discard', 'intersection',
'intersection_update', 'issubset', 'issuperset', 'pop', 'remove',
'symmetric_difference', 'symmetric_difference_update', 'union',
'union_update', 'update']

IronPython
>>> sys.path.append("\\Python24\\lib")
>>> from sets import Set as set
# 同じ


p. 130 に組み込みモジュールの違いがある。ガーベッジコレクション (gc) が .NET Framework の System.GC を使っているから互換性が低くなるとかは仕方あるまい。正規表現 (re) の互換性が低いのが痛いか。あとで要確認。.NET の System.Text.RegularExpressions で実装されているようだ。

copy_reg というモジュールが、IronPython だけにある( clr とかもそうだけど、それは当然として)。copy_reg は Pickle やオブジェクトをコピーするためのツールのようだ。このあたり、あとで調べる。

pickle や StringIO なんかも pure python のモジュールはないので、cXXX を使うことになる。まあ、これは速度的なメリットがあるから、それでもいいが、人の作ったモジュールを使うときには場合によっては書き換える必要が出てくるところかな。

IronPython
>>> import pickle
Traceback (most recent call last):
File , line 0, in <stdin>##14
File , line 0, in __import__##4
ImportError: No module named pickle
>>> import cPickle

>>> import StringIO
Traceback (most recent call last):
File , line 0, in <stdin>##30
File , line 0, in __import__##4
ImportError: No module named StringIO
>>> import cStringIO

CPython だけで提供される組み込みモジュール (p.132)は、

_codecs_cn, _codecs_hk, _codecs_iso2022, _codecs_jp, _codecs_kr, _codecs_tw, _csv, _heapq, _hostshot, _multibytecodec, _subprocess, _symtable, _winreg, array, audioop, cmath, imageop, md5, msvcrt, nmap, parser, regx, rgbimg, select, sha, signal, strop, xxsubtype, zipimport

cmath は、math があるからいいとして、md5 とか sha とか使えないと嫌だなとか思ったが、ちゃんと組み込まれているので、 import md5 も import sha も OK。array 使えないとダメじゃんと思ったが、import array は OK。csv とか使えないのは痛い。

「regx」は「regex」の typo か?まあ、使っていないし、Deprecated なモジュールだから問題なし。parser はんぐっ。msvcrt や _winreg は、.NET でやれって感じか。

time モジュールは、ctime の振る舞いが違う。IronPython は Windows の時刻書式に指定された文字列を返すのか。ふーん。tzname も、IronPython が文字列を返しているのに対して、CPython はタプルを返している。こういうレベルで微妙にはまるところが、あれこれあるのかなぁ。

IronPython
>>> import time
>>>print time.ctime()
土 4 05 19:47:19 2008
>>> time.tzname
u'\u6771\u4eac (\u6a19\u6e96\u6642)'
>>> print time.tzname
東京 (標準時)

CPython
>>> import time
>>> print time.ctime()
'Sat Apr 05 19:47:37 2008'

>>> time.tzname
('\x93\x8c\x8b\x9e (\x95W\x8f\x80\x8e\x9e)',
'\x93\x8c\x8b\x9e (\x95W\x8f\x80\x8e\x9e)')
>>> print time.tzname
('\x93\x8c\x8b\x9e (\x95W\x8f\x80\x8e\x9e)',
'\x93\x8c\x8b\x9e (\x95W\x8f\x80\x8e\x9e)')
>>> t= time.tzname
>>> for a in t:
... print a
...
東京 (標準時)
東京 (標準時)

os モジュールもないのは、ちょっと CPython のスクリプトを再利用するときに痛い。nt モジュールはあるから、

>>> import os
Traceback (most recent call last):
File , line 0, in <stdin>##98
File , line 0, in __import__##4
ImportError: No module named os

>>> import nt as os
>>> dir(os)
['O_APPEND', 'O_BINARY', 'O_CREAT', 'O_EXCL', 'O_NOINHERIT',
'O_RANDOM', 'O_RDONLY', 'O_RDWR', 'O_SEQUENTIAL', 'O_SHORT_LIVED',
'O_TEMPORARY', 'O_TEXT', 'O_TRUNC', 'O_WRONLY', 'P_NOWAIT', 'P_NOWAITO',
'P_WAIT', '__builtins__', '__class__','__dict__', '__doc__', '__init__',
'__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '_exit', 'abort', 'chdir', 'chmod', 'close', 'environ',
'error', 'fdopen', 'fstat', 'getcwd', 'getcwdu', 'getpid', 'listdir',
'lstat', 'mkdir', 'open', 'popen', 'popen2', 'popen3', 'putenv', 'read',
'remove', 'rename', 'rmdir', 'spawnl', 'spawnle', 'spawnv', 'spawnve',
'startfile', 'stat', 'stat_result', 'tempnam', 'times', 'tmpfile',
'tmpnam', 'unlink', 'unsetenv', 'urandom', 'utime', 'waitpid', 'write']

>>> os.path
Traceback (most recent call last):
File , line 0, in <stdin>##105
AttributeError: 'module' object has no attribute 'path'

としても、path 関連はない。.NET のクラスライブラリを使いなさいってことか。ん-っ。p.143 には次のようにある。

.NET Framework は異機種OSを前提にした CLI に基づいているため、異機種のパス表現などを取得数ためのクラスライブラリが用意されています。これらのライブラリを使うことで、異なる OS の CLI とプログラムを共通化できます。

でも、実際のところ既存のものを流用するときには痛い。

math モジュールの定数や数学関数は、IronPython より CPython の方が精度が高いようだ。確認してみると、pi の精度からして違っている。使う人によっては注意が必要か。

IronPython
>>> math.pi
3.14159265359

CPython
>>> import math
>>> math.pi
3.1415926535897931

そういえば、Shift-JIS であっても、バイト文字列が丸ごとユニコード文字列になっているのが困ったちゃん。

>>> s = "日本語どうですか。".encode("shift-jis")
>>> unicode(s)
Traceback (most recent call last):
File , line 0, in <stdin>##56
File mscorlib, line unknown, in GetString
File mscorlib, line unknown, in GetString
File mscorlib, line unknown, in CreateStringFromEncoding
File mscorlib, line unknown, in GetCharCount
File mscorlib, line unknown, in InternalFallback
File mscorlib, line unknown, in Fallback
File mscorlib, line unknown, in Throw
UnicodeDecodeError: インデックス 0 にあるバイト [93] を
指定されたコード ページから Unicode へ変換できません。

Shift-JIS が丸ごとユニコード文字列になっている場合は、decode してやればユニコード文字列になるのね。

>>> s0 = "日本語どうです。"
>>> s0
u'\u65e5\u672c\u8a9e\u3069\u3046\u3067\u3059\u3002'
>>> s1 = s0.encode("shift-jis")
s1
'\x93\xfa\x96{\x8c\xea\x82\xc7\x82\xa4\x82\xc5\x82\xb7\x81B'
>>> s2 = s1.decode(s1)
>>> s2
u'\u65e5\u672c\u8a9e\u3069\u3046\u3067\u3059\u3002'

バイナリモードで、Shift-JIS の文字が入っている test.txt を開いた場合の例が、 p.129 に載っていた。バイナリモードで開くと、Shift-JIS のまま読み込まれるけれど、でもやっぱり丸ごとユニコード文字列になっているので、デコードしてユニコードにしてあげますと。なるほど。

f=open("test.txt" ,"rb")
for line in f:
wk = line.decode("shift-jis")

f.close()

とりあえず、part 3の半分ぐらいまで (p.146) まで読み終えた。



なかのひと






最終更新日  2008年04月06日 01時43分02秒
コメント(0) | コメントを書く
[IronPython] カテゴリの最新記事

Copyright (c) 1997-2020 Rakuten, Inc. All Rights Reserved.