- 20081004: typo修正及び説明追加
Python2.6きましたね。ということで、自分用にも主な変更点メモ。なぐり書きなのでミス多いかも。個人的な注目部分は
- with文
- multiprocessing
- itertoolsへのメソッド追加
- ABCの導入
- クラスデコレータの導入
- ネットワーク系ライブラリ(http,ftp,telnet..etc)でタイムアウトが設定できるようになった。
あたりですかね。ではどうぞ。
Python 3.0由来の変更点
-
複素数へオブジェクトを変換する
__complex__メソッド。 -
例外補足のためのもう一つ書き方:
except TypeError as exc -
build-inの
reduce()に加え、functools.reduceの追加。(3.0ではreduceはfunctools経由でしか使えない)
3.0では他にもbuild-in関数に変更がある。3.0互換のコードを書きたいなら必要に応じてfrom future_builtins import hex,mapのようにimportすること。
また、-3コマンドラインスイッチにより3.0で削除される機能を使っている場合、警告を出せる。
PEP 343: 'with' statement
- with open('/etc/passwd', 'r') as f:
- for line in f:
- print line
- ... more processing code ...
-
withに入るとオブジェクトの
__enter__()、抜けるときに__exit__(type, value, traceback)が呼ばれる。例外発生しなかった場合、type, value,tracebackはNone。 -
contextlibを使うと簡単に書ける。
PEP 399: メインモジュールからの明示的相対的import
Pythonでは-mスイッチでモジュールをスクリプトとして動かせる。が、パッケージ内部のモジュールを動かそうとした場合、相対的importが上手く働かない。本修正で、__package__属性がモジュールに追加された。この属性がある場合、__name__の代わりにこの値からの相対importを行う。
PEP302スタイルのインポータは__package__を必要に応じてセットできる。runpyモジュールの-mスイッチはこれを行っているので、パッケージ内からスクリプトを実行しても相対的importは正しく動く。
PEP 371: multiprocessing module
プロセス間通信を実装したモジュール。並列計算などを実装できる。詳しくはAtsushiさんの記事参照
PEP3101: さらに高度な文字列フォーマット
3.0では%オペレータはさらに高機能になる。2.6ではこの%をstr.formatメソッドで実装している。
- "User ID: {0}".format("root") -> "User ID: root"
- 'User ID: {uid} Last seen: {last_login}'.format(
- uid='root',
- last_login = '5 Mar 2008 07:20') ->
- 'User ID: root Last seen: 5 Mar 2008 07:20'
- 'Platform: {0.platform}\nPython version: {0.version}'.format(sys) ->
- 'Platform: darwin\n
- Python version: 2.6a1+ (trunk:61261M, Mar 5 2008, 20:29:41) \n
- [GCC 4.0.1 (Apple Computer, Inc. build 5367)]'
- fmt = '{0:15} ${1:>6}'
- fmt.format('Registration', 35) ->
- 'Registration $ 35'
くわしくはPEP3101参照。
PEP3105: 関数としてのprint
3.0でprint文はprint関数になる。2.6では__future__に定義されている。
- from __future__ import print_function
- print('# of entries', len(dictionary), file=sys.stderr)
- def print(*args, sep=' ', end='\n', file=None)
PEP 3112: Byte リテラル
3.0では文字列はデフォルトでUnicodeになり、8bitリテラルは別に用意される。b'string'かbyteコンストラクタだ。2.6 ではstrとおなじbytes型を定義し、b''記法をサポートする。
また、__future__で文字列リテラルを全てUnicodeにすることができる。
- from __future__ import unicode_literals
- s = ('\u751f\u3080\u304e\u3000\u751f\u3054'
- '\u3081\u3000\u751f\u305f\u307e\u3054')
- print len(s) # 12 Unicode characters
PEP 3116: 新しいI/Oライブラリ
Pythonではダックタイピングにより、ファイル-likeオブジェクトはread(),write()が定義されていればよかった。ただ、文字列を扱う場合readline()が定義されていたほうがよい。このようなケースに応じた基底クラスがPython3.0ではioモジュールに用意される。
- RawIOBase
- BufferedIOBase
- TextIOBase
など。
くわしくはPEP 3116参照。
PEP 3119: Abstract Base Classes
Abstract Base Class(ABC)はJAVAのインターフェースのようなもの。ABCのサポートはABCMetaというメタクラスを含むabcモジュールで構成される。ABCMetaはisinstanceとissubclassのbuilt-in関数で特別に扱われる。
ABCは通常の継承のように
- import collections
- class Storage(collections.MutableMapping):
- ...
ともABCのregister()メソッドをつかって
- import collections
- class Storage:
- ...
- collections.MutableMapping.register(Storage)
ともできる。registerを使えば、組み込み型や他者の書いたクラスをABCとすることができる。
ABCはJAVAと違い、Pythonが自動でそのインターフェースをチェックしてくれるわけではない。チェックするためには
- if not isinstance(d, collections.MutableMapping):
- raise ValueError("Mapping object expected, not %r" % d)
のように書く。
独自のABCは以下のように定義する
- from abc import ABCMeta, abstractmethod, abstractproperty
- class Drawable():
- __metaclass__ = ABCMeta
- @abstractmethod
- def draw(self, x, y, scale=1.0):
- pass
- @abstractproperty
- def readonly(self):
- return self._x
- def draw_doubled(self, x, y):
- self.draw(x, y, scale=2.0)
これでDrawableから派生したクラスでdrawメソッド、readonlyプロパティが定義されていなければTypeErrorが出るようになる。
PEP 3127: 数値リテラル及び文法
3.0では8進数は0開始でなく0o or 0O開始になり、2進数リテラル0b or 0Bがサポートされる。2.6では0開始8進数表記も使えるが0o or 0O開始も使えるし、oct()関数は0開始も文字列を返す。ただし、future_builtins.octは0o開始の文字列を返す。また、int,long関数は0oと0b開始文字列も扱えるようになった。
PEP 3129: クラスデコレータ
- @foo
- @bar
- class A:
- pass
が
- class A:
- pass
- A = foo(bar(A))
と同義になる。
PEP 3141: 数値の型階層
3.0ではSchemeに習った数値の型階層が導入される。これらの型はnumbersモジュールを通して2.6にバックポートされた。
-
Number
-
Complex
-
Real :
floor()とtrunc()を定義-
Rational :
numeratorとdenominatorを定義。実装はfractionsモジュールで。- Integral
-
Rational :
-
Real :
-
Complex
また、math.trunc()も3.0からバックポートされた。fractionはこのように使う。
- >>> from fractions import Fraction
- >>> a = Fraction(2, 3)
- >>> b = Fraction(2, 5)
- >>> float(a), float(b)
- (0.66666666666666663, 0.40000000000000002)
- >>> a+b
- Fraction(16, 15)
- >>> a/b
- Fraction(5, 3)
- >>> (2.5) .as_integer_ratio()
- (5, 2)
- >>> (3.1415) .as_integer_ratio()
- (7074029114692207L, 2251799813685248L)
- >>> (1./3) .as_integer_ratio()
- (6004799503160661L, 18014398509481984L)
その他の言語の変更
**kw引数にPythonの辞書以外のUserDictのようなどんなマッピングでも使えるようになった。next(iterator, [default])メソッド追加。見ての通りiteratorの次の要素を、なければdefaultを返す。タプルに
index()とcount()が追加された(listと同じ)。組み込み型のsliceのサポートが向上。
プロパティが
getter,setter,deleterというデコレータをサポート。python code- class C(object):
- @property
- def x(self):
- return self._x
- @x.setter
- def x(self, value):
- self._x = value
- @x.deleter
- def x(self):
- del self._x
- class D(C):
- @C.x.getter
- def x(self):
- return self._x * 2
- @x.setter
- def x(self, value):
- self._x = value / 2
setのintersection(), intersection_update(), union(), update(), difference(), difference_update()が引数に複数のiterableを取れるようになった。浮動小数点に関する様々な改良が追加された。
親クラスから
__hash__()を継承したクラスで__hash__ = Noneとすることでhashableでないことを示せる。Exceptionのインタフェースが変更。message属性がdeprecated。GeneratorExitの親クラスがExceptionからBaseExceptionに変更Generatorオブジェクトに
gi_code属性を追加。compile()関数でキーワード引数が取れるようになった。complexコンストラクタでカッコにかこわれている数値がOKになった。complex('(3+4j)')string.translate()に変換テーブルとしてNoneを渡せるようになった。Noneは恒等変換として扱われる。dir()組み込み関数が、引数に渡されたオブジェクトの__dir__()メソッドを見るようになった。__dir__()は文字列のlistを返す必要がある。これにより__getattr__()や__getattribute__()で、擬似属性みたいなのを実現しているクラスでもそのリストが返せる。instance methodオブジェクトで
im_selfを__self__、im_funcを__func__でも参照できるようになった。class文内で
locals()を使った場合、自由変数(クラスの属性でない変数)は含まれなくなった。
新規、改善、非推奨モジュール
3.0警告モードで以下のモジュールは非推奨。
- audiodev, bgenlocations, buildtools, bundlebuilder, Canvas, compiler, dircache, dl, fpformat, gensuitemodule, ihooks, imageop, imgfile, linuxaudiodev, mhlib, mimetools, multifile, new, pure, statvfs, sunaudiodev, test.testall, and toaiff.
asyncore,asynchatでメンテ再開。多くのパッチやバグフィックスが含まれた。cgiでクエリ文字列付きPOSTリクエストにおいてクエリ文字列が解釈されるようになった。(/add.py?category=1へのPOSTなど)parse_qsとparse_qslがcgiモジュールからurlparseモジュールへ。cgiでもまだ使えるがPendingDeprecationWarningが出る。cmathモジュールが改良された。
collections.namedtupleが新しく定義。python code- >>> var_type = collections.namedtuple('variable',
- ... 'id name type size')
- # Names are separated by spaces or commas.
- # 'id, name, type, size' would also work.
- >>> var_type._fields
- ('id', 'name', 'type', 'size')
- >>> var = var_type(1, 'frequency', 'int', 4)
- >>> print var[0], var.id # Equivalent
- 1 1
- >>> print var[2], var.type # Equivalent
- int int
- >>> var._asdict()
- {'size': 4, 'type': 'int', 'id': 1, 'name': 'frequency'}
- >>> v2 = var._replace(name='amplitude')
- >>> v2
- variable(id=1, name='amplitude', type='int', size=4)
collections.dequeがmaxlen引数を取れるようになった。maxlenを超えて要素を追加すると自動で先頭が破棄される。datetimeモジュールのstrftime()で'%f'が扱えるようになった。decimalモジュールでexp(),log10()が追加、またas_tuple()でsign,digits,exponentをフィールドとするnamed tupleを得られる。difflib.SequenceMathcerクラスがa,b,size属性をもったnamed tupleを返すようになった。ftplibでタイムアウトが設定できるようになった。glob.glob()がunicodeファイル名を返すようになった。gopherlib削除。heapqモジュールにmerge(iter1, iter2, ...)とheappushpop(heap, item)が追加。httplib.HTTPConnectionでタイムアウトが設定できるようになった。inspectモジュールの関数の多くがnamed tupleを返すようになった。itertoolsに多数の関数を追加。- izip_longest(iter1, iter2, ...[, fillvalue])
- product(iter1, iter2, ..., [repeat=N])
- combinations(iterable, r)
- permutations(iter[, r])
-
chain(*iterables)は新しくitertools.chain.from_iterable(iterable)とも書けるように。
mathモジュールに関数を追加。- isinf() ,isnan(): 無限とNaNを判別。
-
copysign() : IEEE 754のサインビットをコピー。
math.copysign(1, -0.0)が-1.0。 - factorial() :階乗を計算。
- fsum() : iterableの数値を足すが、出来る限り精度を失うことを避ける。
- acosh(), asinh() ,atanh()
- log1p()
- trunc() : 0の方向へ丸める。
MmeWriterとmimifyモジュールが非推奨に。emailパッケージを使うこと。md5モジュールが非推奨に。hashlibを使うこと。mmapオブジェクトで文字列検索を行うrfind(),find()メソッドを追加。operatorモジュールにmethodcaller()関数追加。python code- >>> # Equivalent to lambda s: s.replace('old', 'new')
- >>> replacer = operator.methodcaller('replace', 'old', 'new')
- >>> replacer('old wine in old bottles')
- 'new wine in new bottles'
operator.attrgetterでドットを含む名前が取れるように。python code- >>> inst_name = operator.attrgetter(
- ... '__class__.__name__')
- >>> inst_name('')
- 'str'
- >>> inst_name(help)
- '_Helper'
os.walk()でfollowlinks=Falseパラメータ追加。Trueにセットされるとシンボリックリンクをたどる。無限ループ注意。os.path.splitext()でドット始まりのファイル名の扱いが変更に。('.ipython', '')から('', '.ipython')os.path.relpath(path, start='.')が追加。startからの相対パスを返す。pdbに新しいコマンドrunを追加。posixfileモジュールが非推奨に。fcntl.lockf()を変わりに使うこと。pickletoolsにoptimize()関数追加。popen2モジュールが非推奨に。subprocessモジュールを使うこと。randomモジュールのRandomオブジェクトが32-bitと64-bit環境間でpickleできるようになった。またtriangular(low,hight,mode)関数追加。reモジュールで長い正規表現を行うとき、シグナルをチェックするようにしたので、時間のかかる検索に割り込まれても大丈夫になった。また、正規表現は正規表現専用の仮想マシンコードの変換されるがベリファイアがなかったので、不正なコードを実行される可能性があった。今回ベリファイアを追加。rgmimgモジュール削除。sched.schedulerインスタンスにqueue属性追加。この属性は(time,priority,action,argument)から構成されるnamed tupleのリストを返す。selectモジュールがepoll,kqueueシステムコールのラッパ関数を導入。setsモジュールが非推奨に。組み込みset, frozensetを使うこと。shaモジュール非推奨。hashlibモジュールを使うこと。shutil.copytree()にignore=callable引数追加。ignoreでコピーしないファイルリストを返すことが出来る。またignore_patterns関数を使い、以下のようにもできるpython code- shutil.copytree('Doc/library', '/tmp/library',
- ignore=shutil.ignore_patterns('*~', '.svn'))
smtplibでSMTP over SSL, LMTPをサポート。subprocess.Popenオブジェクトにterminate(), kill(), send_signal()追加。sysに様々な追加。-
float.h由来の情報を持ったfloat_infoオブジェクト。 -
.pycや.pyoを作るか制御するdont_write_bytecode -
オブジェクトの使用メモリを取得する
sys.getsizeof()。組み込みオブジェクトは正しい数値を返す。 -
sys.getprofile(),sys.gettrace()
-
telnetlibでタイムアウトが設定できるようになった。tempfile.NamedTemporaryFileでdelete=Falseを指定することで自動削除しなくできる。tempfile.SpooledTemporaryFileを追加。メモリ上に確保し、メモリにのらなくなるとファイルに書き出す。test.test_supportがwith文を使った関数を提供する。textwrapモジュールで空白文字を保持するためdrop_whitespace=Falseを指定できるようになった。timeitモジュールで文字列だけでなくcallableも受け取れるようになった。タートルグラフィックを扱う
turtleモジュールにかなりの改良。urllibでタイムアウトを設定できるようになった。zipfile.ZipFileにextract()とextractall(), open(), read()を追加。ASTを扱う
astモジュール追加JSONを扱う
jsonモジュール追加Property Listを扱う
plistlibモジュール追加。OpenSSLの上に構築された、sslモジュール追加。socketモジュールのSSLサポートはまだ使えるが、3.0では削除される予定。このモジュールを使うためには、通常通りTCPコネクションを張り、ssl.wrap_socket()関数に渡す。3.0由来の組み込み関数を含む
future_builtinsモジュールを追加。-
ascii:repr()と同義。3.0ではrepr()はunicode,ascii()はASCII byte文字列を返す。 -
filter,map: 2.xではリストを, 3.0ではイテレータを返す。 -
hex, oct:__hex__()と__oct__()ではなく、__index__()をよびその結果を変換する。
-
Python2.6への移行
ハッシュできないクラスは
__hash__=Noneを行うべき。collection.deque.__init__()は、iterableの要素を追加する前に自身の内容をクリアする。これはlist.__init__()と同じ。python code- >>> from collections.deque
- >>> a = deque([1,2,3])
- >>> deque.__init__(a, [4,5,6])
- >>> a
- # python2.6 => deque([4,5,6])
- # python2.5 => deque([1,2,3,4,5,6])
object.__init__()はこれまで任意の引数を渡すことができ、これらの引数は無視していた。2.6では余計な引数を渡すとTypeErrorがでる。Decimalコンストラクタは前後に空白があっても大丈夫に。以前はInvalidOperation例外がでていた。一方、Context.create_decimal()は余分な空白があるとConversionSyntax例外が出るようになった。__import__で間違ってファイルパスを渡すと、指定したファイルをimportしていたが、これは決してそのように意図したわけではない。今はこのようなケースをチェックし、ImportErrorを出すようになった。C API:
PyImport_ImportとPyImport_ImportModuleのデフォルトが相対importでなく完全importになった。これは他のモジュールをimportするC拡張に影響する。socket.error例外はIOErrorを継承するようになったので、StandardErrorのサブクラスになった。xmlrpclibはdatetime.dateとdatetime.timeを自動的にxmlrpclib.DateTimeに変換しなくなった。なぜならこの挙動は全てのアプリケーションにとって必ずしも有用とは限らないからだ。xmlrpclibを使っているコードはdateとtimeインスタンスを変換すべきである。3.0警告モード:
Exceptionクラスにスライシングおよびインデックスアクセスすると警告。3.0警告モード: 2つの辞書や、比較メソッドを実装していないオブジェクト間で比較演算子を適応すると警告。ただし、
dict1 == dict2は動く。