Python2.6変更点まとめ

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 モジュールで構成される。 ABCMetaisinstanceissubclass の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 関数は 0o0b 開始文字列も扱えるようになった。

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 : numeratordenominator を定義。実装は fractions モジュールで。
          • Integral

また、 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
  • setintersection(), 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_qsparse_qslcgi モジュールから 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.dequemaxlen 引数を取れるようになった。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の方向へ丸める。
  • MmeWritermimify モジュールが非推奨に。 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() を変わりに使うこと。
  • pickletoolsoptimize() 関数追加。
  • 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.NamedTemporaryFiledelete=False を指定することで自動削除しなくできる。

  • tempfile.SpooledTemporaryFile を追加。メモリ上に確保し、メモリにのらなくなるとファイルに書き出す。

  • test.test_supportwith 文を使った関数を提供する。

  • textwrap モジュールで空白文字を保持するため drop_whitespace=False を指定できるようになった。

  • timeit モジュールで文字列だけでなくcallableも受け取れるようになった。

  • タートルグラフィックを扱う turtle モジュールにかなりの改良。

  • urllib でタイムアウトを設定できるようになった。

  • zipfile.ZipFileextract()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_ImportPyImport_ImportModule のデフォルトが相対importでなく完全importになった。これは他のモジュールをimportするC拡張に影響する。
  • socket.error 例外は IOError を継承するようになったので、 StandardError のサブクラスになった。
  • xmlrpclibdatetime.datedatetime.time を自動的に xmlrpclib.DateTime に変換しなくなった。なぜならこの挙動は全てのアプリケーションにとって必ずしも有用とは限らないからだ。 xmlrpclib を使っているコードは datetime インスタンスを変換すべきである。
  • 3.0警告モード: Exception クラスにスライシングおよびインデックスアクセスすると警告。
  • 3.0警告モード: 2つの辞書や、比較メソッドを実装していないオブジェクト間で比較演算子を適応すると警告。ただし、 dict1 == dict2 は動く。
comments powered by Disqus