Python2.4の新機能
- 著者
- 午前 Kuchling
この記事では、2005年3月30日にリリースされたPython2.4.1の新機能について説明します。
Python2.4は中規模のリリースです。 急進的なPython2.2ほど多くの変更は導入されていませんが、保守的な2.3リリースよりも多くの機能が導入されています。 最も重要な新しい言語機能は、関数デコレータとジェネレータ式です。 他のほとんどの変更は、標準ライブラリに対するものです。
CVSの変更ログによると、Python 2.3と2.4の間で、481のパッチが適用され、502のバグが修正されました。 どちらの数値も過小評価される可能性があります。
この記事では、すべての新機能の完全な仕様を提供するのではなく、各機能の簡単な紹介を提供します。 詳細については、PythonライブラリリファレンスやPythonリファレンスマニュアルなど、Python2.4のドキュメントを参照してください。 多くの場合、実装と設計の理論的根拠の説明については、特定の新機能についてPEPを参照します。
PEP 218:組み込みのセットオブジェクト
Python 2.3では、sets
モジュールが導入されました。 セットデータ型のC実装が、set(iterable)
とfrozenset(iterable)
の2つの新しい組み込み型としてPythonコアに追加されました。 これらは、メンバーシップテスト、シーケンスからの重複の排除、および和集合、共通部分、差、対称差などの数学演算のための高速演算を提供します。
>>> a = set('abracadabra') # form a set from a string
>>> 'z' in a # fast membership testing
False
>>> a # unique letters in a
set(['a', 'r', 'b', 'c', 'd'])
>>> ''.join(a) # convert back into a string
'arbcd'
>>> b = set('alacazam') # form a second set
>>> a - b # letters in a but not in b
set(['r', 'd', 'b'])
>>> a | b # letters in either a or b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b # letters in both a and b
set(['a', 'c'])
>>> a ^ b # letters in a or b but not both
set(['r', 'd', 'b', 'm', 'z', 'l'])
>>> a.add('z') # add a new element
>>> a.update('wxy') # add multiple new elements
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'x', 'z'])
>>> a.remove('x') # take one element out
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'z'])
frozenset()タイプは、 set()の不変バージョンです。 不変でハッシュ可能であるため、辞書キーとして、または別のセットのメンバーとして使用できます。
sets
モジュールは標準ライブラリに残っており、Set
またはImmutableSet
クラスをサブクラス化する場合に役立つことがあります。 現在、モジュールを廃止する予定はありません。
PEP 237:長整数と整数の統合
Python 2.2で開始されたこのPEPの長い移行プロセスは、Python2.4でさらに一歩前進します。 2.3では、int / long統合後に異なる動作をする特定の整数演算が、 FutureWarning 警告をトリガーし、32ビットまたは64ビットに制限された値を返しました(プラットフォームによって異なります)。 2.4では、これらの式は警告を生成しなくなり、代わりに通常は長整数である別の結果を生成します。
問題のある式は、主に左シフトと長い16進数および8進数の定数です。 たとえば、2 << 32
は2.3で警告を表示し、32ビットプラットフォームでは0と評価されます。 Python 2.4では、この式が正解8589934592を返すようになりました。
PEP 289:ジェネレータ式
Python2.2と itertools モジュールで導入されたイテレータ機能により、データセット全体を一度にメモリに保存しなくても、大きなデータセットをループするプログラムを簡単に作成できます。 リスト内包表記は、すべての項目を含むPythonリストオブジェクトを生成するため、この図にはあまり適合しません。 これにより、必然的にすべてのオブジェクトがメモリに取り込まれます。これは、データセットが非常に大きい場合に問題になる可能性があります。 機能的なスタイルのプログラムを作成しようとする場合、次のようなものを作成するのが自然です。
links = [link for link in get_all_links() if not link.followed]
for link in links:
...
それ以外の
for link in get_all_links():
if link.followed:
continue
...
最初の形式はより簡潔で読みやすいかもしれませんが、多数のリンクオブジェクトを扱う場合は、すべてのリンクオブジェクトが同時にメモリに存在しないように、2番目の形式を作成する必要があります。
ジェネレータ式はリスト内包表記と同様に機能しますが、リスト全体を具体化するわけではありません。 代わりに、要素を1つずつ返すジェネレーターを作成します。 上記の例は次のように書くことができます:
links = (link for link in get_all_links() if not link.followed)
for link in links:
...
上記の例のように、ジェネレータ式は常に括弧内に記述する必要があります。 関数呼び出しを示す括弧もカウントされるため、関数にすぐに渡されるイテレーターを作成する場合は、次のように記述できます。
print sum(obj.count for obj in list_all_objects())
ジェネレータ式は、さまざまな小さな点でリスト内包とは異なります。 最も注目すべきは、ループ変数(上記の例では obj )はジェネレーター式の外部からアクセスできないことです。 リスト内包表記は、変数を最後の値に割り当てたままにします。 Pythonの将来のバージョンではこれが変更され、リスト内包表記がこの点でジェネレータ式と一致するようになります。
も参照してください
- PEP 289 -ジェネレータ式
- Raymond Hettingerによって提案され、Hye-ShikChangによって主導された初期の努力でJiwonSeoによって実装されました。
PEP 292:より単純な文字列置換
標準ライブラリのいくつかの新しいクラスは、変数を文字列に置き換えるための代替メカニズムを提供します。 このスタイルの置換は、トレーニングを受けていないユーザーがテンプレートを編集する必要があるアプリケーションに適している場合があります。
変数を名前で置き換える通常の方法は、%
演算子です。
>>> '%(page)i: %(title)s' % {'page':2, 'title': 'The Best of Times'}
'2: The Best of Times'
テンプレート文字列を書くとき、閉じ括弧の後にi
またはs
を忘れがちです。 テンプレートがPythonモジュールにある場合、これは大きな問題ではありません。コードを実行し、「サポートされていない形式の文字」 ValueError を取得して、問題を修正するためです。 ただし、Python言語を知らないユーザーがテンプレート文字列または翻訳を編集しているMailmanなどのアプリケーションを検討してください。 フォーマット文字列の構文は、そのようなユーザーに説明するのが複雑であり、ユーザーが間違えた場合、役立つフィードバックをユーザーに提供することは困難です。
PEP 292は、$
を使用して置換を示す string モジュールにTemplate
クラスを追加します。
>>> import string
>>> t = string.Template('$page: $title')
>>> t.substitute({'page':2, 'title': 'The Best of Times'})
'2: The Best of Times'
キーが辞書にない場合、substitute()
メソッドは KeyError を発生させます。 欠落しているキーを無視するsafe_substitute()
メソッドもあります。
>>> t = string.Template('$page: $title')
>>> t.safe_substitute({'page':3})
'3: $title'
PEP 318:関数とメソッドのデコレータ
Python 2.2は、静的メソッドとクラスメソッドを追加することでPythonのオブジェクトモデルを拡張しましたが、静的メソッドまたはクラスメソッドを定義する新しい方法を提供するためにPythonの構文を拡張しませんでした。 代わりに、通常の方法で def ステートメントを記述し、結果のメソッドを staticmethod()または classmethod()関数に渡してラップする必要がありました。新しいタイプのメソッドとして関数をアップします。 コードは次のようになります。
class C:
def meth (cls):
...
meth = classmethod(meth) # Rebind name to wrapped-up class method
メソッドが非常に長い場合、関数本体の後の classmethod()呼び出しを見逃したり忘れたりしがちです。
そのような定義を読みやすくするために常に構文を追加することが意図されていましたが、2.2のリリース時には、適切な構文は明らかではありませんでした。 今日、優れた構文 still は明らかではありませんが、ユーザーはこの機能へのより簡単なアクセスを求めています。 このニーズを満たすために、新しい構文機能が追加されました。
この新機能は「関数デコレータ」と呼ばれます。 この名前は、 classmethod()、 staticmethod()、およびその仲間たちが関数オブジェクトに追加情報を格納しているという考えに由来しています。 それらは装飾関数であり、詳細が記載されています。
表記はJavaから借用し、'@'
文字をインジケーターとして使用します。 新しい構文を使用すると、上記の例は次のように記述されます。
class C:
@classmethod
def meth (cls):
...
@classmethod
は、meth=classmethod(meth)
割り当ての省略形です。 より一般的には、次の場合:
@A
@B
@C
def f ():
...
これは、次のプレデコレータコードと同等です。
def f(): ...
f = A(B(C(f)))
デコレータは、関数定義の前の行に配置する必要があり、行ごとに1つのデコレータであり、defステートメントと同じ行に配置することはできません。つまり、@A def f(): ...
は不正です。 関数定義は、モジュールレベルまたはクラス内でのみ装飾できます。 クラス定義を装飾することはできません。
デコレータは、デコレーションされる関数を引数として受け取り、同じ関数または新しいオブジェクトのいずれかを返す関数です。 デコレータの戻り値は、結果にさらにデコレータが適用されない限り、呼び出す必要はありません(通常は呼び出し可能ですが)。 独自のデコレータを作成するのは簡単です。 次の簡単な例は、関数オブジェクトに属性を設定するだけです。
>>> def deco(func):
... func.attr = 'decorated'
... return func
...
>>> @deco
... def f(): pass
...
>>> f
<function f at 0x402ef0d4>
>>> f.attr
'decorated'
>>>
もう少し現実的な例として、次のデコレータは、指定された引数が整数であることを確認します。
def require_int (func):
def wrapper (arg):
assert isinstance(arg, int)
return func(arg)
return wrapper
@require_int
def p1 (arg):
print arg
@require_int
def p2(arg):
print arg*2
PEP 318 の例には、必要なタイプを指定し、返されたタイプを確認できる、このアイデアのより洗練されたバージョンが含まれています。
デコレータ関数は引数を取ることができます。 引数が指定されている場合、デコレータ関数はそれらの引数のみで呼び出され、新しいデコレータ関数を返す必要があります。 前述のように、この関数は単一の関数を取り、関数を返す必要があります。 つまり、@A @B @C(args)
は次のようになります。
def f(): ...
_deco = C(args)
f = A(B(_deco(f)))
これを正しく行うのは少し頭がおかしいかもしれませんが、それほど難しくはありません。
関連する小さな変更により、関数のfunc_name
属性が書き込み可能になります。 この属性は、トレースバックで関数名を表示するために使用されるため、デコレータは、構築されて返される新しい関数の名前を変更する必要があります。
も参照してください
- PEP 318 -関数、メソッド、およびクラスのデコレータ
- ケビンDによって書かれました。 Smith、Jim Jewett、およびSkipMontanaro。 関数デコレータを実装するパッチを書いた人は何人かいましたが、実際にチェックインされたのは、Mark Russellによって書かれたパッチ#979728でした。
- https://wiki.python.org/moin/PythonDecoratorLibrary
- このWikiページには、デコレータの例がいくつか含まれています。
PEP 322:逆反復
新しい組み込み関数reversed(seq)
は、シーケンスを受け取り、シーケンスの要素を逆の順序でループするイテレーターを返します。
>>> for i in reversed(xrange(1,4)):
... print i
...
3
2
1
range(1,4)[::-1]
などの拡張スライスと比較して、 reverse()は読みやすく、実行速度が速く、使用するメモリが大幅に少なくなっています。
reverse()はシーケンスのみを受け入れ、任意のイテレータは受け入れないことに注意してください。 イテレータを逆にする場合は、最初に list()を使用してリストに変換します。
>>> input = open('/etc/passwd', 'r')
>>> for line in reversed(list(input)):
... print line
...
root:*:0:0:System Administrator:/var/root:/bin/tcsh
...
PEP 324:新しいサブプロセスモジュール
標準ライブラリは、サブプロセスを実行するためのさまざまな方法を提供し、さまざまな機能とさまざまなレベルの複雑さを提供します。 os.system(command)
は使いやすいですが、遅く(コマンドを実行するシェルプロセスを実行します)、危険です(シェルのメタ文字のエスケープに注意する必要があります)。 popen2
モジュールは、サブプロセスからの標準出力と標準エラーをキャプチャできるクラスを提供しますが、名前がわかりにくいです。 サブプロセスモジュールはこれをクリーンアップし、必要なすべての機能を提供する統合インターフェースを提供します。
popen2
のクラスのコレクションの代わりに、サブプロセスには、Popen
という単一のクラスが含まれ、そのコンストラクターはいくつかの異なるキーワード引数をサポートします。
class Popen(args, bufsize=0, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=False, shell=False,
cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0):
args は通常、サブプロセスとして実行されるプログラムへの引数となる文字列のシーケンスです。 ( shell 引数がtrueの場合、 args は、 os.system()と同様に、解釈のためにシェルに渡される文字列にすることができます。 NS。)
stdin 、 stdout 、および stderr は、サブプロセスの入力、出力、およびエラーストリームを指定します。 ファイルオブジェクトまたはファイル記述子を指定するか、定数subprocess.PIPE
を使用して、サブプロセスと親の間にパイプを作成できます。
コンストラクターには、いくつかの便利なオプションがあります。
- close_fds は、サブプロセスを実行する前に、すべてのファイル記述子を閉じるように要求します。
- cwd は、サブプロセスが実行される作業ディレクトリを指定します(デフォルトでは親の作業ディレクトリが何であれ)。
- env は、環境変数を指定する辞書です。
- preexec_fn は、子が開始される前に呼び出される関数です。
- Universal_newlines は、Pythonの Universal Newlines 機能を使用して、子の入力と出力を開きます。
Popen
インスタンスを作成したら、そのwait()
メソッドを呼び出してサブプロセスが終了するまで一時停止するか、poll()
を呼び出して一時停止せずに終了するかどうかを確認するか、[X176X ] は、文字列 data をサブプロセスの標準入力に送信します。 次に、communicate(data)
は、サブプロセスが標準出力または標準エラーに送信したデータを読み取り、タプル(stdout_data, stderr_data)
を返します。
call()
は、引数をPopen
コンストラクターに渡し、コマンドが完了するのを待って、サブプロセスのステータスコードを返すショートカットです。 os.system()のより安全なアナログとして機能します。
sts = subprocess.call(['dpkg', '-i', '/tmp/new-package.deb'])
if sts == 0:
# Success
...
else:
# dpkg returned an error
...
コマンドは、シェルを使用せずに呼び出されます。 本当にシェルを使用したい場合は、キーワード引数としてshell=True
を追加し、シーケンスの代わりに文字列を指定できます。
sts = subprocess.call('dpkg -i /tmp/new-package.deb', shell=True)
PEPは、シェルとPythonコードのさまざまな例を取り上げ、サブプロセスを使用するPythonコードにそれらがどのように変換されるかを示しています。 PEPのこのセクションを読むことを強くお勧めします。
PEP 327:10進データ型
Pythonは、基になるC double 型に基づいて、データ型として常に浮動小数点(FP)数をサポートしてきました。 ただし、ほとんどのプログラミング言語は浮動小数点型を提供しますが、多くの人(プログラマーでさえ)は、浮動小数点数が特定の小数を正確に表していないことに気づいていません。 新しいDecimal
タイプは、ユーザー指定の精度制限まで、これらの分数を正確に表すことができます。
なぜDecimalが必要なのですか?
制限は、浮動小数点数に使用される表現から生じます。 FP番号は、次の3つの要素で構成されています。
- 正または負の符号。
- 仮数。1桁の2進数の後に小数部分が続きます。 たとえば、基数2表記の
1.01
は、1 + 0/2 + 1/4
、または10進表記の1.25です。 - 表示された数値のどこに小数点があるかを示す指数。
たとえば、数値1.25には正の符号、1.01の仮数値(2進数)、および0の指数(小数点をシフトする必要はありません)があります。 数値5の符号と仮数は同じですが、仮数に4を掛けるため(2の指数2の累乗)、指数は2になります。 1.25 * 4は5に等しい。
最近のシステムは通常、IEEE754と呼ばれる標準に準拠する浮動小数点サポートを提供します。 Cの double タイプは通常、64ビットのIEEE 754番号として実装され、仮数に52ビットのスペースを使用します。 つまり、数値は52ビットの精度でしか指定できません。 展開が際限なく繰り返される数値を表現しようとすると、52ビット後に展開が切断されます。 残念ながら、ほとんどのソフトウェアは基数10で出力を生成する必要があり、基数10の一般的な分数は、多くの場合、バイナリで小数を繰り返します。 たとえば、10進数の1.1は2進数1.0001100110011 ...
です。 .1 = 1/16 + 1/32 +1/256に加えて無数の追加項。 IEEE 754は、52桁の後に無限に繰り返される小数を切り落とす必要があるため、表現はわずかに不正確です。
番号を印刷すると、この不正確さがわかる場合があります。
>>> 1.1
1.1000000000000001
FPから10進文字列への変換はCライブラリによって提供され、ほとんどのCライブラリは適切な出力を生成しようとするため、数値を出力するときに不正確さが常に表示されるとは限りません。 ただし、表示されていない場合でも、不正確さが残っているため、後続の操作でエラーが拡大する可能性があります。
多くのアプリケーションでは、これは重要ではありません。 ポイントをプロットしてモニターに表示している場合、1.1と1.1000000000000001の差は小さすぎて表示できません。 多くの場合、レポートは出力を特定の小数点以下の桁数に制限します。数値を小数点以下2桁、3桁、さらには8桁に丸めると、エラーが明らかになることはありません。 ただし、それが重要なアプリケーションの場合、独自のカスタム算術ルーチンを実装するのは大変な作業です。
そのため、Decimal
タイプが作成されました。
Decimalタイプ
新しいモジュール decimal がPythonの標準ライブラリに追加されました。 Decimal
とContext
の2つのクラスが含まれています。 Decimal
インスタンスは数値を表し、Context
インスタンスは、精度やデフォルトの丸めモードなどのさまざまな設定をまとめるために使用されます。
Decimal
インスタンスは、通常のPython整数やFP番号のように、不変です。 一度作成すると、インスタンスが表す値を変更することはできません。 Decimal
インスタンスは、整数または文字列から作成できます。
>>> import decimal
>>> decimal.Decimal(1972)
Decimal("1972")
>>> decimal.Decimal("1.1")
Decimal("1.1")
符号、10進数のタプルとして表される仮数、および指数を含むタプルを提供することもできます。
>>> decimal.Decimal((1, (1, 4, 7, 5), -2))
Decimal("-14.75")
注意事項:符号ビットはブール値であるため、0は正、1は負です。
浮動小数点数からの変換には少し問題があります。1.1を表すFP数は、正確に1.1の場合、または1.1に加えて不正確なものが導入された場合、10進数に変換する必要がありますか。 決定は、問題を回避し、そのような変換をAPIから除外することでした。 代わりに、必要な精度を使用して浮動小数点数を文字列に変換し、その文字列をDecimal
コンストラクターに渡す必要があります。
>>> f = 1.1
>>> decimal.Decimal(str(f))
Decimal("1.1")
>>> decimal.Decimal('%.12f' % f)
Decimal("1.100000000000")
Decimal
インスタンスを作成したら、それらに対して通常の数学演算を実行できます。 1つの制限:べき乗には整数の指数が必要です:
>>> a = decimal.Decimal('35.72')
>>> b = decimal.Decimal('1.73')
>>> a+b
Decimal("37.45")
>>> a-b
Decimal("33.99")
>>> a*b
Decimal("61.7956")
>>> a/b
Decimal("20.64739884393063583815028902")
>>> a ** 2
Decimal("1275.9184")
>>> a**b
Traceback (most recent call last):
...
decimal.InvalidOperation: x ** (non-integer)
Decimal
インスタンスを整数と組み合わせることができますが、浮動小数点数と組み合わせることができません。
>>> a + 4
Decimal("39.72")
>>> a + 4.5
Traceback (most recent call last):
...
TypeError: You can interact Decimal only with int, long or Decimal data types.
>>>
Decimal
番号は math および cmath モジュールで使用できますが、操作が実行される前にすぐに浮動小数点数に変換されることに注意してください。精度と精度が失われる可能性があります。 また、Decimal
ではなく、通常の浮動小数点数が返されます。
>>> import math, cmath
>>> d = decimal.Decimal('123456789012.345')
>>> math.sqrt(d)
351364.18288201344
>>> cmath.sqrt(-d)
351364.18288201344j
Decimal
インスタンスにはDecimal
を返すsqrt()
メソッドがありますが、三角関数などの他のものが必要な場合は、それらを実装する必要があります。
>>> d.sqrt()
Decimal("351364.1828820134592177245001")
Contextタイプ
Context
クラスのインスタンスは、10進演算のいくつかの設定をカプセル化します。
prec
は精度、小数点以下の桁数です。rounding
は、丸めモードを指定します。 10進数モジュールには、ROUND_DOWN
、ROUND_CEILING
、ROUND_HALF_EVEN
など、さまざまな可能性の定数があります。traps
は、特定のエラー条件(例外が発生するか、値が返される)が発生したときに何が起こるかを指定する辞書です。 エラー状態の例としては、ゼロ除算、精度の低下、オーバーフローなどがあります。
getcontext()
を呼び出すことで利用できるスレッドローカルのデフォルトコンテキストがあります。 このコンテキストのプロパティを変更して、デフォルトの精度、丸め、またはトラップ処理を変更できます。 次の例は、デフォルトコンテキストの精度を変更した場合の影響を示しています。
>>> decimal.getcontext().prec
28
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0.1428571428571428571428571429")
>>> decimal.getcontext().prec = 9
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0.142857143")
エラー状態のデフォルトのアクションは選択可能です。 モジュールは、無限大や非数値などの特別な値を返すか、例外を発生させることができます。
>>> decimal.Decimal(1) / decimal.Decimal(0)
Traceback (most recent call last):
...
decimal.DivisionByZero: x / 0
>>> decimal.getcontext().traps[decimal.DivisionByZero] = False
>>> decimal.Decimal(1) / decimal.Decimal(0)
Decimal("Infinity")
>>>
Context
インスタンスには、to_eng_string()
やto_sci_string()
などの数値をフォーマットするためのさまざまなメソッドもあります。
詳細については、 10進数モジュールのドキュメントを参照してください。このドキュメントには、クイックスタートチュートリアルとリファレンスが含まれています。
も参照してください
- PEP 327 -10進数のデータ型
- ファクンドバティスタによって書かれ、ファクンドバティスタ、エリックプライス、レイモンドヘッティンガー、アーズ、ティムピーターズによって実装されました。
- http://www.lahey.com/float.htm
- この記事では、Fortranコードを使用して、浮動小数点の不正確さが引き起こす可能性のある問題の多くを説明しています。
- http://speleotrove.com/decimal/
- 10進数ベースの表現の説明。 この表現は標準として提案されており、新しいPython10進型の基礎となっています。 この資料の多くは、Rexx言語の設計者であるMikeCowlishawによって書かれました。
PEP 328:複数行のインポート
言語の変更の1つは、モジュールから多くの名前を簡単にインポートできるようにすることを目的とした小さな構文の調整です。 from module import names
ステートメントでは、 names はコンマで区切られた名前のシーケンスです。 シーケンスが非常に長い場合は、同じモジュールから複数のインポートを書き込むか、バックスラッシュを使用して次のように行末をエスケープできます。
from SimpleXMLRPCServer import SimpleXMLRPCServer,\
SimpleXMLRPCRequestHandler,\
CGIXMLRPCRequestHandler,\
resolve_dotted_attribute
Python 2.4での構文の変更により、名前を括弧で囲むことができます。 Pythonは括弧で囲まれた式内の改行を無視するため、バックスラッシュは不要になります。
from SimpleXMLRPCServer import (SimpleXMLRPCServer,
SimpleXMLRPCRequestHandler,
CGIXMLRPCRequestHandler,
resolve_dotted_attribute)
PEPは、すべての import ステートメントが絶対インポートであり、先頭の.
文字が相対インポートを示すことも提案しています。 PEPのこの部分は、Python 2.4では実装されていませんが、Python2.5では完了しました。
PEP 331:ロケールに依存しないフロート/文字列変換
locale モジュールを使用すると、Pythonソフトウェアでさまざまな変換を選択し、特定の国または言語にローカライズされた規則を表示できます。 ただし、Pythonの実装のさまざまな関数では、数値ロケールを'C'
ロケールに設定したままにする必要があるため、モジュールは数値ロケールを変更しないように注意しました。 多くの場合、これはコードがCライブラリのatof()
関数を使用していたことが原因でした。
ただし、数値ロケールを設定しないと、サードパーティのCライブラリを使用する拡張機能で問題が発生しました。これは、正しいロケールが設定されていないためです。 やる気を起こさせる例はGTK +で、そのユーザーインターフェイスウィジェットは現在のロケールで数字を表示していませんでした。
PEPで説明されている解決策は、ロケール設定を無視して、ASCIIのみの変換を実行する3つの新しい関数をPythonAPIに追加することです。
PyOS_ascii_strtod(str, ptr)
とPyOS_ascii_atof(str, ptr)
はどちらも、文字列をC double に変換します。PyOS_ascii_formatd(buffer, buf_len, format, d)
は、 double をASCII文字列に変換します。
これらの関数のコードはGLibライブラリ( https://developer.gnome.org/glib/stable/ )からのものであり、その開発者は関連する関数を親切に再ライセンスし、Python SoftwareFoundationに寄贈しました。 locale モジュールで数値ロケールを変更できるようになり、GTK +などの拡張機能で正しい結果が生成されるようになりました。
その他の言語の変更
Python2.4がコアPython言語に加えるすべての変更は次のとおりです。
関数とメソッドのデコレータが追加されました( PEP 318 )。
組み込みの set()および floatset()タイプが追加されました( PEP 218 )。 その他の新しい組み込み機能には、
reversed(seq)
機能( PEP 322 )が含まれます。ジェネレータ式が追加されました( PEP 289 )。
特定の数値式は、32ビットまたは64ビットに制限された値を返さなくなりました( PEP 237 )。
from module import names
ステートメント( PEP 328 )で、名前のリストを括弧で囲むことができるようになりました。dict.update()メソッドは、 dict コンストラクターと同じ引数形式を受け入れるようになりました。 これには、マッピング、キーと値のペアの反復可能、およびキーワード引数が含まれます。 (Raymond Hettingerによる寄稿。)
文字列メソッド
ljust()
、rjust()
、およびcenter()
は、スペース以外の塗りつぶし文字を指定するためのオプションの引数を取るようになりました。 (Raymond Hettingerによる寄稿。)文字列は、
split()
メソッドと同様に機能するが、文字列の末尾から分割されるrsplit()
メソッドも取得しました。 (Sean Reifschneiderによる寄稿。)>>> 'www.python.org'.split('.', 1) ['www', 'python.org'] 'www.python.org'.rsplit('.', 1) ['www.python', 'org']
リストの
sort()
メソッドに、 cmp 、 key 、および reverse の3つのキーワードパラメーターが追加されました。 これらのパラメーターにより、sort()
の一般的な使用法が簡単になります。 これらのパラメータはすべてオプションです。cmp パラメーターの場合、値は2つのパラメーターを取り、パラメーターの比較方法に応じて-1、0、または+1を返す比較関数である必要があります。 この関数は、リストを並べ替えるために使用されます。 以前は、これが
sort()
に提供できる唯一のパラメーターでした。key は、リスト要素を受け取り、その要素の比較キーを返す単一パラメーター関数である必要があります。 次に、比較キーを使用してリストを並べ替えます。 次の例では、リストを大文字と小文字を区別せずに並べ替えます。
>>> L = ['A', 'b', 'c', 'D'] >>> L.sort() # Case-sensitive sort >>> L ['A', 'D', 'b', 'c'] >>> # Using 'key' parameter to sort list >>> L.sort(key=lambda x: x.lower()) >>> L ['A', 'b', 'c', 'D'] >>> # Old-fashioned way >>> L.sort(cmp=lambda x,y: cmp(x.lower(), y.lower())) >>> L ['A', 'b', 'c', 'D']
cmp パラメーターを使用する最後の例は、大文字と小文字を区別しない並べ替えを実行する古い方法です。 動作しますが、 key パラメーターを使用するよりも遅くなります。 key を使用すると、リスト内の要素ごとに
lower()
メソッドが1回呼び出され、 cmp を使用すると、比較ごとに2回呼び出されるため、 key を使用すると節約できます。lower()
メソッドの呼び出し時。単純なキー関数と比較関数の場合、代わりに非バインドメソッドを使用することで lambda 式を回避できることがよくあります。 たとえば、上記の大文字と小文字を区別しない並べ替えは、次のように記述するのが最適です。
>>> L.sort(key=str.lower) >>> L ['A', 'b', 'c', 'D']
最後に、 reverse パラメーターはブール値を取ります。 値がtrueの場合、リストは逆の順序で並べ替えられます。
L.sort(); L.reverse()
の代わりに、L.sort(reverse=True)
と書くことができるようになりました。ソートの結果は安定していることが保証されています。 これは、同じキーを持つ2つのエントリが、入力されたのと同じ順序で返されることを意味します。 たとえば、人のリストを名前で並べ替えてから、リストを年齢で並べ替えると、同じ年齢の人が名前で並べ替えられた順序で、年齢で並べ替えられたリストが作成されます。
(
sort()
へのすべての変更はRaymond Hettingerによって提供されました。)インプレース list.sort()メソッドのように機能するが、式で使用できる新しい組み込み関数
sorted(iterable)
があります。 違いは次のとおりです。入力は任意の反復可能です。
新しく形成されたコピーはソートされ、元のコピーはそのまま残ります。 と
式は、ソートされた新しいコピーを返します
>>> L = [9,7,8,3,2,4,1,6,5] >>> [10+i for i in sorted(L)] # usable in a list comprehension [11, 12, 13, 14, 15, 16, 17, 18, 19] >>> L # original is left unchanged [9,7,8,3,2,4,1,6,5] >>> sorted('Monty Python') # any iterable may be an input [' ', 'M', 'P', 'h', 'n', 'n', 'o', 'o', 't', 't', 'y', 'y'] >>> # List the contents of a dict sorted by key values >>> colormap = dict(red=1, blue=2, green=3, black=4, yellow=5) >>> for k, v in sorted(colormap.iteritems()): ... print k, v ... black 4 blue 2 green 3 red 1 yellow 5
(Raymond Hettingerによる寄稿。)
整数演算は
OverflowWarning
をトリガーしなくなりました。OverflowWarning
警告はPython2.5では消えます。インタプリタは、名前を取り、
sys.path
で対応するモジュールを検索し、そのモジュールをスクリプトとして実行する新しいスイッチ -m を取得しました。 たとえば、Pythonプロファイラーをpython -m profile
で実行できるようになりました。 (Nick Coghlanによる寄稿。)eval(expr, globals, locals)
およびexecfile(filename, globals, locals)
関数とexec
ステートメントは、 locals パラメーターの任意のマッピングタイプを受け入れるようになりました。 以前は、これは通常のPython辞書である必要がありました。 (Raymond Hettingerによる寄稿。)zip()組み込み関数と
itertools.izip()
は、引数なしで呼び出された場合に空のリストを返すようになりました。 以前は、 TypeError 例外が発生していました。 これにより、可変長引数リストでの使用により適したものになります。>>> def transpose(array): ... return zip(*array) ... >>> transpose([(1,2,3), (4,5,6)]) [(1, 4), (2, 5), (3, 6)] >>> transpose([]) []
(Raymond Hettingerによる寄稿。)
モジュールのインポート中に障害が発生しても、部分的に初期化されたモジュールオブジェクトが
sys.modules
に残ることはなくなりました。 残された不完全なモジュールオブジェクトは、同じモジュールのインポートをさらに成功させるためにだまされ、混乱を招くエラーにつながります。 (Tim Petersによって修正されました。)None は定数になりました。 新しい値を名前
None
にバインドするコードは、構文エラーになりました。 (Raymond Hettingerによる寄稿。)
最適化
- リストとタプルのスライスの内部ループが最適化され、実行速度が約3分の1になりました。 辞書の内部ループも最適化され、
keys()
、values()
、items()
、iterkeys()
、itervalues()
、およびiteritems()
。 (Raymond Hettingerによる寄稿。) - リストを拡大および縮小するための機械は、速度とスペース効率のために最適化されました。 コードパスがより効率的になり、基盤となるシステム
realloc()
の使用頻度が少なくなるため、リストへの追加とリストからのポップがより高速に実行されるようになりました。 リスト内包表記も役立ちます。list.extend()
も最適化され、ベースリストを拡張する前に引数を一時リストに変換しなくなりました。 (Raymond Hettingerによる寄稿。) - list()、 tuple()、 map()、 filter()、および zip()
__len__()
メソッドを提供する非シーケンス引数を使用すると、数倍高速に実行されるようになりました。 (Raymond Hettingerによる寄稿。) - メソッド
list.__getitem__()
、dict.__getitem__()
、およびdict.__contains__()
は、wrapper_descriptor
オブジェクトではなくmethod_descriptor
オブジェクトとして実装されるようになりました。 この形式のアクセスは、パフォーマンスを2倍にし、汎関数の引数としての使用に適したものにします:map(mydict.__getitem__, keylist)
。 (Raymond Hettingerによる寄稿。) - 新しいオペコード
LIST_APPEND
が追加されました。これは、リスト内包表記用に生成されたバイトコードを簡素化し、それらを約3分の1高速化します。 (Raymond Hettingerによる寄稿。) - のぞき穴バイトコードオプティマイザが改善され、より短く、より高速なバイトコードが生成されます。 驚くべきことに、結果のバイトコードはより読みやすくなります。 (レイモンドヘッティンガーによって強化されました。)
s = s + "abc"
およびs += "abc"
の形式のステートメントでの文字列の連結は、特定の状況でより効率的に実行されるようになりました。 この最適化は、Jythonなどの他のPython実装には存在しないため、これに依存しないでください。 多数のストリングを効率的に接着する場合は、ストリングのjoin()
メソッドを使用することをお勧めします。 (Armin Rigoによる寄稿。)
2.4最適化の最終的な結果は、Python2.4がPython2.3よりも5 % f aster、Python2.2よりも35 % f asterでpystoneベンチマークを実行することです。 (pystoneは特に優れたベンチマークではありませんが、Pythonのパフォーマンスの最も一般的に使用される測定値です。 独自のアプリケーションは、Python 2.4のメリットが多かれ少なかれ示される場合があります。)
新規、改善、および非推奨のモジュール
いつものように、Pythonの標準ライブラリは多くの機能強化とバグ修正を受けました。 これは、モジュール名のアルファベット順にソートされた、最も注目すべき変更の部分的なリストです。 変更のより完全なリストについては、ソースツリーのMisc/NEWS
ファイルを参照するか、すべての詳細についてCVSログを調べてください。
asyncore モジュールの
loop()
関数に count パラメーターが追加され、ポーリングループを通過するパスの数を制限できるようになりました。 デフォルトでは、それでも永久ループになります。base64 モジュールは、Base64、Base32、およびBase16のエンコードとデコードをより完全に RFC 3548 でサポートするようになりました。これには、オプションの大文字と小文字の折りたたみとオプションの代替アルファベットが含まれます。 (Barry Warsawによる寄稿。)
bisect モジュールには、パフォーマンスを向上させるための基盤となるC実装が含まれるようになりました。 (Dmitry Vasilievによる寄稿)
Hye-Shik Changによって維持されている東アジアコーデックのCJKCodecsコレクションは、2.4に統合されました。 新しいエンコーディングは次のとおりです。
中国語(PRC):gb2312、gbk、gb18030、big5hkscs、hz
中国語(ROC):big5、cp950
- 日本語:cp932、euc-jis-2004、euc-jp、euc-jisx0213、iso-2022-jp、
iso-2022-jp-1、iso-2022-jp-2、iso-2022-jp-3、iso-2022-jp-ext、iso-2022-jp-2004、shift-jis、shift-jisx0213、shift- jis-2004
韓国語:cp949、euc-kr、johab、iso-2022-kr
他のいくつかの新しいエンコーディングが追加されました:HP Roman8、ISO_8859-11、ISO_8859-16、PCTP-154、およびTIS-620。
UTF-8およびUTF-16コーデックは、部分的な入力の受信にうまく対応できるようになりました。 以前は、
StreamReader
クラスはより多くのデータを読み取ろうとしていたため、ストリームからデコードを再開できませんでした。read()
メソッドは可能な限り多くのデータを返すようになり、今後の呼び出しは前の呼び出しが中断したところからデコードを再開します。 (WalterDörwaldによって実装されました。)さまざまな特殊なコレクションデータ型用の新しい collections モジュールがあります。 現在、
deque
という1つのタイプのみが含まれています。これは、両端からの要素の効率的な追加と削除をサポートする両端キューです。>>> from collections import deque >>> d = deque('ghi') # make a new deque with three items >>> d.append('j') # add a new entry to the right side >>> d.appendleft('f') # add a new entry to the left side >>> d # show the representation of the deque deque(['f', 'g', 'h', 'i', 'j']) >>> d.pop() # return and remove the rightmost item 'j' >>> d.popleft() # return and remove the leftmost item 'f' >>> list(d) # list the contents of the deque ['g', 'h', 'i'] >>> 'h' in d # search the deque True
Queue
および threading モジュールなどのいくつかのモジュールは、パフォーマンスを向上させるために collections.deque を利用するようになりました。 (Raymond Hettingerによる寄稿。)ConfigParser
クラスがわずかに強化されました。read()
メソッドは、正常に解析されたファイルのリストを返すようになりました。 set()メソッドは、 value が渡されると、 TypeError を発生させます。文字列ではない引数。 (JohnBelmonteとDavidGoodgerによる寄稿。)curses モジュールは、ncurses拡張機能
use_default_colors()
をサポートするようになりました。 端末が透明度をサポートしているプラットフォームでは、これにより透明な背景を使用できます。 (JörgLehmannによる寄稿。)difflib モジュールには、2つのバージョンのテキストを並べて比較するHTMLテーブルを作成する
HtmlDiff
クラスが含まれるようになりました。 (Dan Gassによる寄稿。)email パッケージがバージョン3.0に更新され、非推奨のさまざまなAPIが削除され、2.3より前のPythonバージョンのサポートが削除されました。 パッケージの3.0バージョンは、
email.FeedParser
モジュールで利用可能なMIMEメッセージ用の新しいインクリメンタルパーサーを使用します。 新しいパーサーは、メッセージ全体をメモリに読み込む必要がなく、メッセージの形式が正しくない場合でも例外を発生させません。 代わりに、メッセージのdefect
属性に問題を記録します。 (Anthony Baxter、Barry Warsaw、Thomas Woutersなどによって開発されました。)heapq モジュールはCに変換されました。 その結果、速度が10倍向上し、モジュールは大量のデータの処理に適しています。 さらに、このモジュールには2つの新しい関数
nlargest()
とnsmallest()
があり、ヒープを使用して、完全な並べ替えを行うことなく、データセット内のN個の最大値または最小値を検索します。 (Raymond Hettingerによる寄稿。)httplib
モジュールには、さまざまなHTTP関連のRFCドキュメントで定義されているHTTPステータスコードの定数が含まれるようになりました。 定数の名前は、OK
、CREATED
、CONTINUE
、MOVED_PERMANENTLY
などです。 完全なリストを取得するには、pydocを使用してください。 (Andrew Elandによる寄稿。)imaplib モジュールは、IMAPのTHREADコマンド(Yves Dionneによる寄稿)と新しい
deleteacl()
およびmyrights()
メソッド(Arnaud Mazinによる寄稿)をサポートするようになりました。itertools モジュールは
groupby(iterable[, *func*])
機能を獲得しました。 iterable は、要素のストリームを返すために繰り返すことができるものであり、オプションの func パラメーターは、要素を受け取り、キー値を返す関数です。 省略した場合、キーは単に要素自体です。groupby()
は、要素をキーの値が一致するサブシーケンスにグループ化し、キー値とサブシーケンスのイテレータを含む一連の2タプルを返します。これを明確にするための例を次に示します。 key 関数は、数値が偶数か奇数かを返すだけなので、
groupby()
の結果は、奇数または偶数の連続した実行を返します。>>> import itertools >>> L = [2, 4, 6, 7, 8, 9, 11, 12, 14] >>> for key_val, it in itertools.groupby(L, lambda x: x % 2): ... print key_val, list(it) ... 0 [2, 4, 6] 1 [7] 0 [8] 1 [9, 11] 0 [12, 14] >>>
groupby()
は通常、ソートされた入力で使用されます。groupby()
のロジックは、Unixuniq
フィルターに似ており、重複する要素を削除、カウント、または識別するのに便利です。>>> word = 'abracadabra' >>> letters = sorted(word) # Turn string into a sorted list of letters >>> letters ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r'] >>> for k, g in itertools.groupby(letters): ... print k, list(g) ... a ['a', 'a', 'a', 'a', 'a'] b ['b', 'b'] c ['c'] d ['d'] r ['r', 'r'] >>> # List unique letters >>> [k for k, g in groupby(letters)] ['a', 'b', 'c', 'd', 'r'] >>> # Count letter occurrences >>> [(k, len(list(g))) for k, g in groupby(letters)] [('a', 5), ('b', 2), ('c', 1), ('d', 1), ('r', 2)]
(Hye-Shik Changによる寄稿。)
itertools は、 iterator を複製する N 独立イテレーターを返す
tee(iterator, N)
という名前の関数も取得しました。 N を省略した場合、デフォルトは2です。>>> L = [1,2,3] >>> i1, i2 = itertools.tee(L) >>> i1,i2 (<itertools.tee object at 0x402c2080>, <itertools.tee object at 0x402c2090>) >>> list(i1) # Run the first iterator to exhaustion [1, 2, 3] >>> list(i2) # Run the second iterator to exhaustion [1, 2, 3]
tee()
は、イテレータによって返された値のコピーを保持する必要があることに注意してください。 最悪の場合、それらすべてを保持する必要があるかもしれません。 したがって、入力の長いストリームで先頭のイテレータが末尾のイテレータよりもはるかに先に実行できる場合は、これを慎重に使用する必要があります。 間隔が大きい場合は、代わりに list()を使用することをお勧めします。 イテレータが互いに密接に追跡する場合、tee()
が理想的です。 可能なアプリケーションには、ブックマーク、ウィンドウ処理、または先読みイテレータが含まれます。 (Raymond Hettingerによる寄稿。)locale モジュールには、特定のエンコーディングを指定する
bind_textdomain_codeset()
や、選択したエンコーディングでメッセージを返すl*gettext()
関数のファミリーなど、いくつかの関数が追加されました。 (Gustavo Niemeyerによる寄稿。)ログ構成を簡素化するために、 logging パッケージの
basicConfig()
関数にいくつかのキーワード引数が追加されました。 デフォルトの動作では、メッセージを標準エラーに記録しますが、特定のファイルに記録したり、記録形式を変更したり、記録レベルを設定したりするために、さまざまなキーワード引数を指定できます。 例えば:import logging logging.basicConfig(filename='/var/log/application.log', level=0, # Log all messages format='%(levelname):%(process):%(thread):%(message)')
logging パッケージへのその他の追加には、
log(level, msg)
コンビニエンスメソッド、およびログファイルを一定の間隔でローテーションするTimedRotatingFileHandler
クラスが含まれます。 モジュールにはすでにRotatingFileHandler
があり、ファイルが特定のサイズを超えるとログをローテーションしました。 どちらのクラスも、他の回転ハンドラーを実装するために使用できる新しいBaseRotatingHandler
クラスから派生しています。(Vinay Sajipによって実装された変更。)
marshal モジュールは、データ構造を解凍するときにインターンされた文字列を共有するようになりました。 これにより、特定のピクルス文字列のサイズが縮小される場合がありますが、主な効果は、
.pyc
ファイルを大幅に小さくすることです。 (MartinvonLöwisによる寄稿。)nntplib モジュールの
NNTP
クラスは、description()
およびdescriptions()
メソッドを取得して、単一のグループまたはグループの範囲のニュースグループの説明を取得しました。 (JürgenAによる寄稿。 アーハルト。)演算子モジュールに
attrgetter(attr)
とitemgetter(index)
の2つの新しい関数が追加されました。 どちらの関数も、単一の引数を取り、対応する属性または項目を返す呼び出し可能オブジェクトを返します。 これらの呼び出し可能オブジェクトは、 map()または sorted()と一緒に使用すると、優れたデータ抽出機能になります。 例えば:>>> L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)] >>> map(operator.itemgetter(0), L) ['c', 'd', 'a', 'b'] >>> map(operator.itemgetter(1), L) [2, 1, 4, 3] >>> sorted(L, key=operator.itemgetter(1)) # Sort list by second tuple item [('d', 1), ('c', 2), ('b', 3), ('a', 4)]
(Raymond Hettingerによる寄稿。)
optparse モジュールはさまざまな方法で更新されました。 モジュールはメッセージを gettext.gettext()に渡すようになり、Optikのヘルプメッセージとエラーメッセージを国際化できるようになりました。 オプションのヘルプメッセージに文字列
'%default'
を含めることができるようになりました。これは、オプションのデフォルト値に置き換えられます。 (Greg Wardによる寄稿)長期計画では、 email パッケージを優先して、将来のPythonリリースで
rfc822
モジュールを廃止する予定です。 このため、email.Utils.formatdate()
機能が変更され、rfc822.formatdate()
の代わりに使用できるようになりました。 これを念頭に置いて、新しい電子メール処理コードを作成することをお勧めします。 (変更はAnthony Baxterによって実装されました。)新しい
urandom(n)
関数が os モジュールに追加され、 n バイトのランダムデータを含む文字列が返されました。 この関数は、Linux上の/dev/urandom
やWindowsCryptoAPIなどのプラットフォーム固有のランダム性のソースへのアクセスを提供します。 (Trevor Perrinによる寄稿。)別の新しい関数:
os.path.lexists(path)
は、シンボリックリンクであるかどうかに関係なく、パスで指定されたファイルが存在する場合にtrueを返します。 これは、 path が存在しない宛先を指すシンボリックリンクである場合にfalseを返す既存のos.path.exists(path)
関数とは異なります。 (Beni Cherniavskyによる寄稿。)os モジュールの下にある posix モジュールに新しい
getsid()
関数が追加されました。 (Jによる寄稿。 レイナー。)poplib モジュールがPOPoverSSLをサポートするようになりました。 (Hector Urtubiaによる寄稿。)
profile モジュールは、C拡張機能をプロファイルできるようになりました。 (Nick Bastinによる寄稿。)
ランダムモジュールには、
getrandbits(N)
と呼ばれる新しいメソッドがあり、長整数 N ビットの長さを返します。 既存のrandrange()
メソッドは、必要に応じてgetrandbits()
を使用するようになり、任意の大きな乱数の生成がより効率的になりました。 (Raymond Hettingerによる寄稿。)re モジュールで受け入れられる正規表現言語は、
(?(group)A|B)
として記述された単純な条件式で拡張されました。 group は、数値のグループIDか、式の前半で(?P<group>...)
で定義されたグループ名です。 指定されたグループが一致した場合、正規表現パターン A が文字列に対してテストされます。 グループが一致しなかった場合は、代わりにパターン B が使用されます。 (Gustavo Niemeyerによる寄稿。)re モジュールも、Gustavo Niemeyerによる大量の作業のおかげで、再帰的ではなくなりました。 再帰的な正規表現エンジンでは、特定のパターンによって大量のCスタックスペースが消費され、スタックがオーバーフローする可能性がありました。 たとえば、
a
文字の30000バイトの文字列を式(a|b)+
と照合した場合、文字ごとに1つのスタックフレームが消費されました。 Python 2.3は、スタックオーバーフローをチェックし、 RuntimeError 例外を発生させようとしましたが、特定のパターンがチェックを回避する可能性があり、運が悪ければPythonがセグメンテーション違反を起こす可能性があります。 Python 2.4の正規表現エンジンは、このパターンに問題なく一致させることができます。signal モジュールは、 signal.signal()関数のパラメーターに対してより厳密なエラーチェックを実行するようになりました。 たとえば、
SIGKILL
信号にハンドラーを設定することはできません。 以前のバージョンのPythonはこれを静かに受け入れますが、2.4では RuntimeError 例外が発生します。socket モジュールに2つの新機能が追加されました。
socketpair()
は接続されたソケットのペアを返し、getservbyport(port)
は指定されたポート番号のサービス名を検索します。 (DaveColeとBarryWarsawによる寄稿。)sys.exitfunc()
関数は非推奨になりました。 コードは、既存の atexit モジュールを使用する必要があります。このモジュールは、複数の出口関数の呼び出しを正しく処理します。 最終的に、sys.exitfunc()
は純粋に内部インターフェースになり、 atexit によってのみアクセスされます。tarfile モジュールは、デフォルトでGNU形式のtarファイルを生成するようになりました。 (LarsGustäbelによる寄稿。)
threading モジュールには、スレッドローカルデータをサポートするためのエレガントでシンプルな方法があります。 モジュールには、属性値がさまざまなスレッドに対してローカルである
local
クラスが含まれています。import threading data = threading.local() data.number = 42 data.url = ('www.python.org', 80)
他のスレッドは、
number
およびurl
属性に独自の値を割り当てて取得できます。local
をサブクラス化して、属性を初期化したり、メソッドを追加したりできます。 (Jim Fultonによる寄稿。)timeit モジュールは、タイミングループ中に定期的なガベージコレクションを自動的に無効にするようになりました。 この変更により、連続するタイミングがより比較可能になります。 (Raymond Hettingerによる寄稿。)
weakref モジュールは、Python関数、クラスインスタンス、セット、frozensets、deques、配列、ファイル、ソケット、正規表現パターンオブジェクトなど、さまざまなオブジェクトをサポートするようになりました。 (Raymond Hettingerによる寄稿。)
xmlrpclib
モジュールは、単一のHTTP操作で複数のXML-RPC呼び出しを送信するためのマルチ呼び出し拡張機能をサポートするようになりました。 (Brian Quinlanによる寄稿。)mpz
、rotor
、およびxreadlines
モジュールは削除されました。
doctest
doctest モジュールは、EdwardLoperとTimPetersのおかげでかなりのリファクタリングを受けました。 テストは doctest.testmod()を実行するのと同じくらい簡単ですが、リファクタリングにより、モジュールの操作をさまざまな方法でカスタマイズできます。
新しいDocTestFinder
クラスは、指定されたオブジェクトのdocstringからテストを抽出します。
def f (x, y):
""">>> f(2,2)
4
>>> f(3,2)
6
"""
return x*y
finder = doctest.DocTestFinder()
# Get list of DocTest instances
tests = finder.find(f)
次に、新しいDocTestRunner
クラスは個々のテストを実行し、結果の要約を生成できます。
runner = doctest.DocTestRunner()
for t in tests:
tried, failed = runner.run(t)
runner.summarize(verbose=1)
上記の例では、次の出力が生成されます。
1 items passed all tests:
2 tests in f
2 tests in 1 items.
2 passed and 0 failed.
Test passed.
DocTestRunner
は、OutputChecker
クラスのインスタンスを使用して、期待される出力と実際の出力を比較します。 このクラスは、その動作をカスタマイズするさまざまなフラグを取ります。 野心的なユーザーは、OutputChecker
のまったく新しいサブクラスを作成することもできます。
デフォルトの出力チェッカーは、いくつかの便利な機能を提供します。 たとえば、 doctest.ELLIPSIS オプションフラグを使用すると、期待される出力の省略記号(...
)が任意のサブ文字列と一致するため、わずかに異なる出力に対応しやすくなります。
def o (n):
""">>> o(1)
<__main__.C instance at 0x...>
>>>
"""
別の特別な文字列<BLANKLINE>
は、空白行に一致します。
def p (n):
""">>> p(1)
<BLANKLINE>
>>>
"""
もう1つの新機能は、 doctest.REPORT_UDIFF (unified diffs)、 doctest.REPORT_CDIFF (context diffs)、または doctestを指定して、出力のdiffスタイルの表示を生成することです。 REPORT_NDIFF (デルタスタイル)オプションフラグ。 例えば:
def g (n):
""">>> g(4)
here
is
a
lengthy
>>>"""
L = 'here is a rather lengthy list of words'.split()
for word in L[:n]:
print word
doctest.REPORT_UDIFF を指定して上記の関数のテストを実行すると、次の出力が得られます。
**********************************************************************
File "t.py", line 15, in g
Failed example:
g(4)
Differences (unified diff with -expected +actual):
@@ -2,3 +2,3 @@
is
a
-lengthy
+rather
**********************************************************************
ビルドとCAPIの変更
PythonのビルドプロセスとCAPIへの変更の一部は次のとおりです。
- 拡張関数からの一般的な戻り値に対して、 Py_RETURN_NONE 、 Py_RETURN_TRUE 、および Py_RETURN_FALSE の3つの新しい便利なマクロが追加されました。 (Brett Cannonによる寄稿。)
- 別の新しいマクロ Py_CLEAR(obj)は、 obj の参照カウントを減らし、 obj をnullポインターに設定します。 (Jim Fultonによる寄稿。)
- 新しい関数
PyTuple_Pack(N, obj1, obj2, ..., objN)
は、Pythonオブジェクトの可変長引数リストからタプルを作成します。 (Raymond Hettingerによる寄稿。) - 新しい関数
PyDict_Contains(d, k)
は、ルックアッププロセス中に発生した例外をマスクすることなく、高速な辞書ルックアップを実装します。 (Raymond Hettingerによる寄稿。) - Py_IS_NAN(X)マクロは、floatまたはdouble引数 X がNaNの場合、1を返します。 (Tim Petersによる寄稿。)
- Cコードは、新しい PyEval_ThreadsInitialized()関数を使用して、スレッド操作が実行されたかどうかを通知することにより、不要なロックを回避できます。 この関数がfalseを返す場合、ロック操作は必要ありません。 (Nick Coghlanによる寄稿。)
- 新しい関数 PyArg_VaParseTupleAndKeywords()は、 PyArg_ParseTupleAndKeywords()と同じですが、引数の数の代わりに
va_list
を取ります。 (Greg Chapmanによる寄稿。) - 新しいメソッドフラグ
METH_COEXISTS
を使用すると、スロットで定義された関数を同じ名前の PyCFunction と共存させることができます。 これにより、set.__contains__()
などのメソッドのアクセス時間が半分になります。 (Raymond Hettingerによる寄稿。) - Pythonは、Pythonコアを開発する人々を支援することを目的として、インタープリター自体の追加のプロファイリングを使用して構築できるようになりました。
--enable-profiling
を configure スクリプトに提供すると、インタープリターを gprof でプロファイリングでき、--with-tsc
スイッチを提供すると、Pentiumのタイムスタンプを使用したプロファイリングが可能になります。 -カウンターレジスタ。--with-tsc
スイッチの名前は少し間違っていることに注意してください。プロファイリング機能はPowerPCプラットフォームでも機能しますが、そのプロセッサアーキテクチャではそのレジスタを「TSCレジスタ」とは呼びません。 (Jeremy Hyltonによる寄稿。) tracebackobject
タイプはPyTracebackObject
に名前が変更されました。
ポート固有の変更
- Windowsポートは、バージョン6だけでなくMSVC ++ 7.1でもビルドできるようになりました。 (MartinvonLöwisによる寄稿。)
Python2.4への移植
このセクションでは、コードの変更が必要になる可能性のある前述の変更を一覧表示します。
- 左シフトおよび16進数/ 8進数の定数が大きすぎると、 FutureWarning がトリガーされなくなり、32ビットまたは64ビットに制限された値が返されます。 代わりに、長整数を返します。
- 整数演算は
OverflowWarning
をトリガーしなくなりました。OverflowWarning
警告はPython2.5では消えます。 - zip()組み込み関数と
itertools.izip()
は、引数なしで呼び出された場合に TypeError 例外を発生させる代わりに、空のリストを返すようになりました。 - datetime モジュールによって提供される
date
インスタンスと datetime インスタンスを比較できなくなりました。 異なるクラスの2つのインスタンスは常に等しくなくなり、相対比較(<
、>
)により TypeError が発生します。 dircache.listdir()
は、空のリストを返す代わりに、呼び出し元に例外を渡すようになりました。LexicalHandler.startDTD()
は、パブリックIDとシステムIDを間違った順序で受信するために使用されていました。 これは修正されました。 間違った順序に依存しているアプリケーションは修正する必要があります。- fcntl.ioctl()は、 mutate 引数が省略され、関連している場合に警告するようになりました。
- tarfile モジュールは、デフォルトでGNU形式のtarファイルを生成するようになりました。
- モジュールのインポート中に障害が発生しても、部分的に初期化されたモジュールオブジェクトが
sys.modules
に残ることはなくなりました。 - None は定数になりました。 新しい値を名前
None
にバインドするコードは、構文エラーになりました。 signals.signal()
関数は、特定の不正な値に対して RuntimeError 例外を発生させるようになりました。 以前は、これらのエラーはサイレントに渡されていました。 たとえば、SIGKILL
信号にハンドラーを設定することはできなくなりました。
謝辞
著者は、この記事のさまざまなドラフトについて提案、修正、支援を提供してくれた次の人々に感謝します:Koray Can、Hye-Shik Chang、Michael Dyck、Raymond Hettinger、Brian Hurt、Hamish Lawson、Fredrik Lundh、Sean Reifschneider、Sadruddin Rejeb。