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
1with open('/etc/passwd', 'r') as f:
2 for line in f:
3 print line
4 ... 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 メソッドで実装している。
1"User ID: {0}".format("root") -> "User ID: root"
2
3'User ID: {uid} Last seen: {last_login}'.format(
4 uid='root',
5 last_login = '5 Mar 2008 07:20') ->
6 'User ID: root Last seen: 5 Mar 2008 07:20'
7
8'Platform: {0.platform}\nPython version: {0.version}'.format(sys) ->
9 'Platform: darwin\n
10 Python version: 2.6a1+ (trunk:61261M, Mar 5 2008, 20:29:41) \n
11 [GCC 4.0.1 (Apple Computer, Inc. build 5367)]'
12
13fmt = '{0:15} ${1:>6}'
14fmt.format('Registration', 35) ->
15 'Registration $ 35'
くわしくは PEP3101 参照。
PEP3105: 関数としての print
3.0で print 文は print 関数になる。2.6では __future__ に定義されている。
1from __future__ import print_function
2print('# of entries', len(dictionary), file=sys.stderr)
3
4def print(*args, sep=' ', end='\n', file=None)
PEP 3112: Byte リテラル
3.0` では文字列はデフォルトでUnicodeになり、8bitリテラルは別に用意される。 b'string' か byte コンストラクタだ。2.6 ではstrとおなじ bytes 型を定義し、 b'' 記法をサポートする。
また、 __future__ で文字列リテラルを全てUnicodeにすることができる。
1from __future__ import unicode_literals
2
3s = ('\u751f\u3080\u304e\u3000\u751f\u3054'
4 '\u3081\u3000\u751f\u305f\u307e\u3054')
5
6print 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は通常の継承のように
1import collections
2class Storage(collections.MutableMapping):
3 ...
ともABCの register() メソッドをつかって
1import collections
2class Storage:
3 ...
4collections.MutableMapping.register(Storage)
ともできる。 register を使えば、組み込み型や他者の書いたクラスを ABC とすることができる。
ABCはJAVAと違い、Pythonが自動でそのインターフェースをチェックしてくれるわけではない。チェックするためには
1if not isinstance(d, collections.MutableMapping):
2 raise ValueError("Mapping object expected, not %r" % d)
のように書く。
独自のABCは以下のように定義する
1from abc import ABCMeta, abstractmethod, abstractproperty
2
3class Drawable():
4 __metaclass__ = ABCMeta
5
6 @abstractmethod
7 def draw(self, x, y, scale=1.0):
8 pass
9
10 @abstractproperty
11 def readonly(self):
12 return self._x
13
14 def draw_doubled(self, x, y):
15 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: クラスデコレータ
1@foo
2@bar
3class A:
4 pass
が
1class A:
2 pass
3
4A = 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はこのように使う。
1>>> from fractions import Fraction
2>>> a = Fraction(2, 3)
3>>> b = Fraction(2, 5)
4>>> float(a), float(b)
5(0.66666666666666663, 0.40000000000000002)
6>>> a+b
7Fraction(16, 15)
8>>> a/b
9Fraction(5, 3)
10>>> (2.5) .as_integer_ratio()
11(5, 2)
12>>> (3.1415) .as_integer_ratio()
13(7074029114692207L, 2251799813685248L)
14>>> (1./3) .as_integer_ratio()
15(6004799503160661L, 18014398509481984L)
その他の言語の変更
**kw引数にPythonの辞書以外のUserDictのようなどんなマッピングでも使えるようになった。next(iterator, [default])メソッド追加。見ての通りiteratorの次の要素を、なければdefaultを返す。- タプルに
index()とcount()が追加された(listと同じ)。 - 組み込み型のsliceのサポートが向上。
- プロパティが
getter,setter,deleterというデコレータをサポート。
1class C(object):
2 @property
3 def x(self):
4 return self._x
5
6 @x.setter
7 def x(self, value):
8 self._x = value
9
10 @x.deleter
11 def x(self):
12 del self._x
13
14class D(C):
15 @C.x.getter
16 def x(self):
17 return self._x * 2
18
19 @x.setter
20 def x(self, value):
21 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が新しく定義。
1>>> var_type = collections.namedtuple('variable',
2... 'id name type size')
3# Names are separated by spaces or commas.
4# 'id, name, type, size' would also work.
5>>> var_type._fields
6('id', 'name', 'type', 'size')
7
8>>> var = var_type(1, 'frequency', 'int', 4)
9>>> print var[0], var.id # Equivalent
101 1
11>>> print var[2], var.type # Equivalent
12int int
13>>> var._asdict()
14{'size': 4, 'type': 'int', 'id': 1, 'name': 'frequency'}
15>>> v2 = var._replace(name='amplitude')
16>>> v2
17variable(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()関数追加。
1>>> # Equivalent to lambda s: s.replace('old', 'new')
2>>> replacer = operator.methodcaller('replace', 'old', 'new')
3>>> replacer('old wine in old bottles')
4'new wine in new bottles'
operator.attrgetterでドットを含む名前が取れるように。
1>>> inst_name = operator.attrgetter(
2... '__class__.__name__')
3>>> inst_name('')
4'str'
5>>> inst_name(help)
6'_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関数を使い、以下のようにもできる
1shutil.copytree('Doc/library', '/tmp/library',
2 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__()と同じ。
1>>> from collections.deque
2>>> a = deque([1,2,3])
3>>> deque.__init__(a, [4,5,6])
4>>> a
5# python2.6 => deque([4,5,6])
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は動く。