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
というデコレータをサポート。
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
が新しく定義。
>>> 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()
関数追加。
>>> # 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
でドットを含む名前が取れるように。
>>> 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
関数を使い、以下のようにもできる
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__()
と同じ。
>>> 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
は動く。