Python2.5の新機能
- 著者
- 午前 Kuchling
この記事では、Python2.5の新機能について説明します。 Python2.5の最終リリースは2006年8月に予定されています。 PEP 356 は、計画されているリリーススケジュールについて説明しています。
Python 2.5での変更は、言語とライブラリの改善の興味深い組み合わせです。 広く役立つパッケージがいくつか追加されたため、ライブラリの機能強化はPythonのユーザーコミュニティにとってより重要になると思います。 新しいモジュールには、XML処理用のElementTree(xml.etree
)、SQLiteデータベースモジュール(sqlite
)、およびC関数を呼び出すための ctypes モジュールが含まれます。
言語の変更は中途半端な意味を持っています。 いくつかの楽しい新機能が追加されましたが、それらのほとんどは、毎日使用する機能ではありません。 条件式は、新しい構文を使用して最終的に言語に追加されました。 セクション PEP 308:条件式を参照してください。 新しい「 with 」ステートメントにより、クリーンアップコードの記述が容易になります(セクション PEP 343:「with」ステートメント)。 値をジェネレーターに渡すことができるようになりました(セクション PEP 342:新しいジェネレーター機能)。 インポートは、絶対インポートまたは相対インポートとして表示されるようになりました(セクション PEP 328:絶対および相対インポート)。 例外処理のいくつかのコーナーケースはより適切に処理されます(セクション PEP 341:統一されたtry / exception / finally )。 これらの改善はすべて価値がありますが、特定の言語機能の改善です。 それらのどれもPythonのセマンティクスへの広範な変更ではありません。
言語とライブラリの追加に加えて、その他の改善とバグ修正がソースツリー全体で行われました。 SVN変更ログを検索すると、Python 2.4と2.5の間で353のパッチが適用され、458のバグが修正されていることがわかります。 (どちらの数値も過小評価される可能性があります。)
この記事は、新機能の完全な仕様となることを目的としたものではありません。 代わりに、役立つ例を使用して変更を簡単に紹介します。 詳細については、 https://docs.python.org にあるPython2.5のドキュメントを常に参照する必要があります。 完全な実装と設計の理論的根拠を理解したい場合は、特定の新機能についてPEPを参照してください。
このドキュメントに対するコメント、提案、およびエラーレポートは大歓迎です。 それらを作成者に電子メールで送信するか、Pythonバグトラッカーでバグを開いてください。
PEP 308:条件式
長い間、ブール値が真であるか偽であるかに応じて値Aまたは値Bを返す式である条件式を作成する方法を人々が要求してきました。 条件式を使用すると、次と同じ効果を持つ単一の代入ステートメントを記述できます。
if condition:
x = true_value
else:
x = false_value
python-devとcomp.lang.pythonの両方で、構文についての退屈な議論が際限なくありました。 投票が行われ、投票者の大多数が何らかの形で条件式を望んでいることがわかりましたが、明らかに過半数が好む構文はありませんでした。 候補には、Cのcond ? true_v : false_v
、if cond then true_v else false_v
、およびその他の16のバリエーションが含まれていました。
Guido van Rossumは、最終的に驚くべき構文を選択しました。
x = true_value if condition else false_value
評価は既存のブール式のようにまだ怠惰であるため、評価の順序は少しジャンプします。 真ん中の condition 式が最初に評価され、 true_value 式は条件が真の場合にのみ評価されます。 同様に、 false_value 式は、条件がfalseの場合にのみ評価されます。
この構文は奇妙で逆に見えるかもしれません。 条件が式の中央にあり、Cのc ? x : y
のように前面にないのはなぜですか? 新しい構文を標準ライブラリのモジュールに適用し、結果のコードがどのように読み取られるかを確認することで、決定を確認しました。 条件式が使用される多くの場合、1つの値は「一般的なケース」であり、1つの値は「例外的なケース」であり、条件が満たされないまれな場合にのみ使用されます。 条件付き構文により、このパターンが少しわかりやすくなります。
contents = ((doc + '\n') if doc else '')
上記のステートメントは、「ここでは、コンテンツには通常doc+'\n'
の値が割り当てられています。 doc が空の場合があります。その場合、特別な場合は空の文字列が返されます。」 明確な一般的および一般的でないケースがない場合、条件式を頻繁に使用することはないと思います。
言語が括弧で囲まれた条件式を必要とするかどうかについての議論がありました。 Python言語の文法ではは括弧を必要としないという決定がなされましたが、スタイルの問題として、常にそれらを使用する必要があると思います。 次の2つのステートメントを検討してください。
# First version -- no parens
level = 1 if logging else 0
# Second version -- with parens
level = (1 if logging else 0)
最初のバージョンでは、読者の目がステートメントを「level = 1」、「if logging」、「else 0」にグループ化し、条件によって level への割り当てが実行されるかどうかが決まると思います。 。 私の意見では、2番目のバージョンの方が読みやすくなっています。これは、割り当てが常に実行され、2つの値から選択されていることが明確になるためです。
角かっこを含めるもう1つの理由:リスト内包表記とラムダのいくつかの奇妙な組み合わせは、誤った条件式のように見える可能性があります。 いくつかの例については、 PEP 308 を参照してください。 条件式を括弧で囲むと、このケースに遭遇することはありません。
PEP 309:部分機能の適用
functools モジュールは、関数型プログラミング用のツールを含むことを目的としています。
このモジュールで役立つツールの1つは、partial()
関数です。 関数型で記述されたプログラムの場合、いくつかのパラメーターが入力された既存の関数のバリアントを作成したい場合があります。 Python関数f(a, b, c)
について考えてみましょう。 f(1, b, c)
と同等の新しい関数g(b, c)
を作成できます。 これを「部分機能適用」といいます。
partial()
は引数(function, arg1, arg2, ... kwarg1=value1, kwarg2=value2)
を取ります。 結果のオブジェクトは呼び出し可能であるため、それを呼び出すだけで、入力された引数を使用して function を呼び出すことができます。
小さいながらも現実的な例を次に示します。
import functools
def log (message, subsystem):
"Write the contents of 'message' to the specified subsystem."
print '%s: %s' % (subsystem, message)
...
server_log = functools.partial(log, subsystem='server')
server_log('Unable to open socket')
これは、PyGTKを使用するプログラムからの別の例です。 ここでは、状況依存のポップアップメニューが動的に作成されています。 メニューオプションに提供されるコールバックは、open_item()
メソッドの部分的に適用されたバージョンであり、最初の引数が提供されています。
...
class Application:
def open_item(self, path):
...
def init (self):
open_func = functools.partial(self.open_item, item_path)
popup_menu.append( ("Open", open_func, 1) )
functools モジュールのもう1つの関数は、update_wrapper(wrapper, wrapped)
関数で、行儀の良いデコレータを作成するのに役立ちます。 update_wrapper()
は、名前、モジュール、およびdocstring属性をラッパー関数にコピーして、ラップされた関数内のトレースバックを理解しやすくします。 たとえば、次のように書くことができます。
def my_decorator(f):
def wrapper(*args, **kwds):
print 'Calling decorated function'
return f(*args, **kwds)
functools.update_wrapper(wrapper, f)
return wrapper
wraps()
は、ラップされた関数の情報をコピーするために独自のデコレータ内で使用できるデコレータです。 前の例の代替バージョンは次のようになります。
def my_decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwds):
print 'Calling decorated function'
return f(*args, **kwds)
return wrapper
も参照してください
- PEP 309 -部分機能アプリケーション
- PEPは、PeterHarrisによって提案および作成されました。 Hye-ShikChangとNickCoghlanによって実装され、RaymondHettingerによって改作されました。
PEP 314:Pythonソフトウェアパッケージv1.1のメタデータ
いくつかの単純な依存関係のサポートがDistutilsに追加されました。 setup()
関数に、requires
、provides
、およびobsoletes
キーワードパラメーターが追加されました。 sdist
コマンドを使用してソースディストリビューションを構築すると、依存関係情報がPKG-INFO
ファイルに記録されます。
もう1つの新しいキーワードパラメータはdownload_url
で、パッケージのソースコードのURLに設定する必要があります。 これは、パッケージインデックスのエントリを検索し、パッケージの依存関係を判別し、必要なパッケージをダウンロードできるようになったことを意味します。
VERSION = '1.0'
setup(name='PyPackage',
version=VERSION,
requires=['numarray', 'zlib (>=1.1.4)'],
obsoletes=['OldPackage']
download_url=('http://www.example.com/pypackage/dist/pkg-%s.tar.gz'
% VERSION),
)
https://pypi.org にあるPythonパッケージインデックスのもう1つの新しい拡張機能は、パッケージのソースアーカイブとバイナリアーカイブを保存することです。 新しい upload Distutilsコマンドは、パッケージをリポジトリにアップロードします。
パッケージをアップロードする前に、 sdist Distutilsコマンドを使用してディストリビューションを構築できる必要があります。 それが機能したら、python setup.py upload
を実行して、パッケージをPyPIアーカイブに追加できます。 オプションで、--sign
および--identity
オプションを指定して、パッケージにGPG署名を付けることができます。
パッケージのアップロードは、MartinvonLöwisとRichardJonesによって実装されました。
も参照してください
- PEP 314 -Pythonソフトウェアパッケージv1.1のメタデータ
- AMによって提案および作成されたPEP Kuchling、Richard Jones、およびFred Drake; リチャードジョーンズとフレッドドレイクによって実装されました。
PEP 328:絶対および相対輸入
PEP 328 のより単純な部分がPython2.4に実装されました。from ... import ...
ステートメントを使用してモジュールからインポートされた名前を括弧で囲むことができるようになり、簡単になりました。多くの異なる名前をインポートします。
より複雑な部分がPython2.5に実装されました。モジュールのインポートは、絶対インポートまたはパッケージ相対インポートを使用するように指定できます。 計画は、Pythonの将来のバージョンで絶対インポートをデフォルトにする方向に進むことです。
次のようなパッケージディレクトリがあるとします。
pkg/
pkg/__init__.py
pkg/main.py
pkg/string.py
これは、pkg.main
およびpkg.string
サブモジュールを含むpkg
という名前のパッケージを定義します。
main.py
モジュールのコードについて考えてみましょう。 ステートメントimport string
を実行するとどうなりますか? Python 2.4以前では、最初にパッケージのディレクトリを調べて相対インポートを実行し、pkg/string.py
を見つけ、そのファイルの内容をpkg.string
モジュールとしてインポートし、そのモジュールはにバインドされます。 pkg.main
モジュールの名前空間にある名前string
。
pkg.string
が必要なものであれば、それで問題ありません。 しかし、Pythonの標準の文字列モジュールが必要な場合はどうでしょうか。 pkg.string
を無視して標準モジュールを探すクリーンな方法はありません。 一般的にはsys.modules
の内容を確認する必要がありましたが、少し汚れています。 HolgerKrekelのpy.std
パッケージは、標準ライブラリimport py; py.std.string.join()
からのインポートを実行するためのよりきちんとした方法を提供しますが、そのパッケージはすべてのPythonインストールで利用できるわけではありません。
string またはpkg.string
のどちらのモジュールを使用するのかについて読者が混乱する可能性があるため、相対インポートに依存するコードの読み取りもあまり明確ではありません。 Pythonユーザーはすぐに、パッケージのサブモジュールの名前に標準ライブラリモジュールの名前を複製しないことを学びましたが、Pythonの将来のバージョンで追加される新しいモジュールにサブモジュールの名前が使用されるのを防ぐことはできません。
Python 2.5では、from __future__ import absolute_import
ディレクティブを使用して、 import の動作を絶対インポートに切り替えることができます。 この絶対インポート動作は、将来のバージョン(おそらくPython 2.7)でデフォルトになります。 絶対インポートがデフォルトになると、import string
は常に標準ライブラリのバージョンを検索します。 ユーザーは可能な限り絶対インポートの使用を開始することをお勧めします。そのため、コードにfrom pkg import string
を記述し始めることをお勧めします。
from ... import
フォームを使用する場合、モジュール名に先頭のピリオドを追加することで、相対的なインポートが可能です。
# Import names from pkg.string
from .string import name1, name2
# Import pkg.string
from . import string
これにより、現在のパッケージに関連する string モジュールがインポートされるため、pkg.main
では、pkg.string
から name1 および name2 がインポートされます。 。 追加の先行期間は、現在のパッケージの親から開始して相対インポートを実行します。 たとえば、A.B.C
モジュールのコードは次のことを実行できます。
from . import D # Imports A.B.D
from .. import E # Imports A.E
from ..F import G # Imports A.F.G
先行ピリオドは、インポートステートメントのimport modname
形式では使用できず、from ... import
形式でのみ使用できます。
も参照してください
- PEP 328 -インポート:マルチラインおよび絶対/相対
- Aahzによって書かれたPEP; ThomasWoutersによって実装されました。
- https://pylib.readthedocs.io/
py.std
パッケージを含むHolgerKrekelによるpyライブラリ。
PEP 338:モジュールをスクリプトとして実行する
スクリプトとしてモジュールを実行するためにPython2.4で追加された -m スイッチは、さらにいくつかの機能を獲得しました。 スイッチは、Pythonインタープリター内のCコードで実装される代わりに、新しいモジュール runpy での実装を使用するようになりました。
runpy モジュールは、より高度なインポートメカニズムを実装しているため、pychecker.checker
などのパッケージでモジュールを実行できるようになりました。 このモジュールは、 zipimport モジュールなどの代替インポートメカニズムもサポートしています。 つまり、.zipアーカイブのパスをsys.path
に追加してから、 -m スイッチを使用してアーカイブからコードを実行できます。
PEP 341:統一された試行/例外/最終
Python 2.5までは、 try ステートメントには2つの種類がありました。 finally ブロックを使用してコードが常に実行されるようにするか、1つ以上の exception ブロックを使用して特定の例外をキャッチできます。 except
ブロックとfinally
ブロックの両方を組み合わせることができませんでした。これは、組み合わせたバージョンの正しいバイトコードの生成が複雑であり、組み合わせたステートメントのセマンティクスが明確でないためです。
Guido van Rossumは、 exception ブロックと finally ブロックを組み合わせるのと同等の機能をサポートするJavaでの作業に時間を費やしました。これにより、ステートメントの意味が明確になりました。 Python 2.5では、次のように書くことができます。
try:
block-1 ...
except Exception1:
handler-1 ...
except Exception2:
handler-2 ...
else:
else-block
finally:
final-block
block-1 のコードが実行されます。 コードで例外が発生した場合、さまざまな exception ブロックがテストされます。例外がクラスException1
の場合、 handler-1 が実行されます。 それ以外の場合、クラスException2
の場合、 handler-2 が実行されます。 例外が発生しない場合は、 else-block が実行されます。
以前に何が起こったとしても、 final-block は、コードブロックが完了し、発生した例外が処理されると実行されます。 例外ハンドラーまたは else-block でエラーが発生し、新しい例外が発生した場合でも、 final-block のコードは実行されます。
PEP 342:新しいジェネレーター機能
Python 2.5は、値をジェネレーターに渡す簡単な方法を追加します。 Python 2.3で導入されたように、ジェネレーターは出力のみを生成します。 イテレータを作成するためにジェネレータのコードが呼び出されると、実行が再開されたときに関数に新しい情報を渡す方法はありませんでした。 一部の情報を渡す機能が役立つ場合があります。 これに対するハックな解決策には、ジェネレーターのコードにグローバル変数を参照させてからグローバル変数の値を変更するか、呼び出し元が変更する可変オブジェクトを渡すことが含まれます。
基本的なジェネレーターのメモリを更新するための簡単な例を次に示します。
def counter (maximum):
i = 0
while i < maximum:
yield i
i += 1
counter(10)
を呼び出すと、結果は0から9までの値を返すイテレーターになります。 yield ステートメントが検出されると、イテレーターは指定された値を返し、関数の実行を一時停止して、ローカル変数を保持します。 イテレータの next()メソッドへの次の呼び出しで実行が再開され、yield
ステートメントの後にピックアップされます。
Python 2.3では、 yield はステートメントでした。 値を返しませんでした。 2.5では、yield
が式になり、変数に割り当てたり、次の操作を実行したりできる値を返します。
val = (yield i)
上記の例のように、戻り値を使用して何かを行うときは、 yield 式を常に括弧で囲むことをお勧めします。 括弧は必ずしも必要ではありませんが、必要なときに覚えておくよりも、常に追加する方が簡単です。
( PEP 342 は、 yield 式は、右側の最上位の式で発生する場合を除いて、常に括弧で囲む必要があるという正確な規則を説明しています。 -課題の手側。 つまり、val = yield i
と書くことはできますが、val = (yield i) + 12
のように、操作がある場合は括弧を使用する必要があります。)
値は、send(value)
メソッドを呼び出すことによってジェネレーターに送信されます。 その後、ジェネレーターのコードが再開され、 yield 式は指定された値を返します。 通常の next()メソッドが呼び出されると、yield
は None を返します。
これは前の例で、内部カウンターの値を変更できるように変更されています。
def counter (maximum):
i = 0
while i < maximum:
val = (yield i)
# If value provided, change counter
if val is not None:
i = val
else:
i += 1
そして、これがカウンターを変更する例です:
>>> it = counter(10)
>>> print it.next()
0
>>> print it.next()
1
>>> print it.send(8)
8
>>> print it.next()
9
>>> print it.next()
Traceback (most recent call last):
File "t.py", line 15, in ?
print it.next()
StopIteration
yield は通常 None を返すため、このケースを常に確認する必要があります。 send()
メソッドがジェネレーター関数を再開するために使用される唯一のメソッドであることが確実でない限り、式でその値を使用しないでください。
send()
に加えて、ジェネレーターには他に2つの新しいメソッドがあります。
throw(type, value=None, traceback=None)
は、ジェネレーター内で例外を発生させるために使用されます。 例外は、ジェネレータの実行が一時停止される yield 式によって発生します。close()
は、ジェネレーター内で新しい GeneratorExit 例外を発生させ、反復を終了します。 この例外を受け取ると、ジェネレーターのコードは GeneratorExit または StopIteration を発生させる必要があります。 GeneratorExit 例外をキャッチして値を返すことは不正であり、 RuntimeError をトリガーします。 関数が他の例外を発生させた場合、その例外は呼び出し元に伝播されます。close()
は、ジェネレーターがガベージコレクションされるときに、Pythonのガベージコレクターによっても呼び出されます。GeneratorExit が発生したときにクリーンアップコードを実行する必要がある場合は、 GeneratorExit をキャッチする代わりに、
try: ... finally:
スイートを使用することをお勧めします。
これらの変更の累積的な効果は、情報の一方通行のプロデューサーからのジェネレーターをプロデューサーとコンシューマーの両方に変えることです。
ジェネレーターは、コルーチン、より一般化された形式のサブルーチンにもなります。 サブルーチンはあるポイントで入力され、別のポイントで終了します(関数の先頭、および return ステートメント)が、コルーチンは多くの異なるポイントで開始、終了、および再開できます(の利回りステートメント)。 Pythonでコルーチンを効果的に使用するためのパターンを理解する必要があります。
close()
メソッドの追加には、明らかではない1つの副作用があります。 close()
は、ジェネレーターがガベージコレクションされるときに呼び出されるため、ジェネレーターが破棄される前に、ジェネレーターのコードが最後に実行される可能性があります。 この最後のチャンスは、ジェネレーターのtry...finally
ステートメントが機能することを保証できることを意味します。 finally 句が常に実行されるようになりました。 したがって、 yield ステートメントをtry...finally
スイートと混在させることができないという構文上の制限が削除されました。 これはちょっとした雑学のように思えますが、 PEP 343 [で記述された with ステートメントを実装するには、ジェネレーターとtry...finally
を使用する必要があります。 X188X]。 この新しいステートメントについては、次のセクションで説明します。
この変更のもう1つのさらに難解な効果:以前は、ジェネレーターのgi_frame
属性は常にフレームオブジェクトでした。 ジェネレーターが使い果たされると、gi_frame
をNone
にすることができるようになりました。
も参照してください
- PEP 342 -拡張ジェネレーターを介したコルーチン
グイドヴァンロッサムとフィリップJによって書かれたPEP。 エビー; PhillipJによって実装されました。 エビー。 コルーチンとしてのジェネレーターのより巧妙な使用例が含まれています。
これらの機能の以前のバージョンは、RaymondHettingerによる PEP 288 、およびSamuelePedroniによる PEP 325 で提案されました。
- https://en.wikipedia.org/wiki/Coroutine
コルーチンのウィキペディアエントリ。
- http://www.sidhe.org/~dan/blog/archives/000178.html
ダン・スガルスキーによって書かれた、Perlの観点からのコルーチンの説明。
PEP 343:「with」ステートメント
' with 'ステートメントは、以前はtry...finally
ブロックを使用して、クリーンアップコードが確実に実行されるようにするコードを明確にします。 このセクションでは、一般的に使用されるステートメントについて説明します。 次のセクションでは、実装の詳細を調べ、このステートメントで使用するオブジェクトを作成する方法を示します。
' with 'ステートメントは、基本構造が次の新しい制御フロー構造です。
with expression [as variable]:
with-block
式が評価され、コンテキスト管理プロトコルをサポートするオブジェクトが生成されます(つまり、__enter__()
メソッドと__exit__()
メソッドがあります。
オブジェクトの__enter__()
は、 with-block が実行される前に呼び出されるため、セットアップコードを実行できます。 また、指定されている場合は、変数という名前にバインドされた値を返す場合があります。 (変数には式の結果が割り当てられていないことに注意してください。)
with-block の実行が終了すると、ブロックで例外が発生した場合でも、オブジェクトの__exit__()
メソッドが呼び出されるため、クリーンアップコードを実行できます。
Python 2.5でステートメントを有効にするには、モジュールに次のディレクティブを追加する必要があります。
from __future__ import with_statement
このステートメントは、Python2.6では常に有効になります。
一部の標準Pythonオブジェクトは、コンテキスト管理プロトコルをサポートするようになり、「 with 」ステートメントで使用できます。 ファイルオブジェクトはその一例です。
with open('/etc/passwd', 'r') as f:
for line in f:
print line
... more processing code ...
このステートメントが実行された後、 for ループがブロックの途中で例外を発生させた場合でも、 f のファイルオブジェクトは自動的に閉じられます。
threading モジュールのロックおよび条件変数は、「 with 」ステートメントもサポートします。
lock = threading.Lock()
with lock:
# Critical section of code
...
ロックはブロックが実行される前に取得され、ブロックが完了すると常に解放されます。
decimal モジュールの新しいlocalcontext()
関数を使用すると、現在の10進数コンテキストを簡単に保存および復元できます。これにより、計算に必要な精度と丸め特性がカプセル化されます。
from decimal import Decimal, Context, localcontext
# Displays with default precision of 28 digits
v = Decimal('578')
print v.sqrt()
with localcontext(Context(prec=16)):
# All code in this block uses a precision of 16 digits.
# The original context is restored on exiting the block.
print v.sqrt()
コンテキストマネージャーの作成
内部的には、「 with 」ステートメントはかなり複雑です。 ほとんどの人は、既存のオブジェクトと一緒に「with
」のみを使用し、これらの詳細を知る必要がないため、必要に応じてこのセクションの残りの部分をスキップできます。 新しいオブジェクトの作成者は、基礎となる実装の詳細を理解する必要があり、読み続ける必要があります。
コンテキスト管理プロトコルの概要は次のとおりです。
- 式が評価され、「コンテキストマネージャー」と呼ばれるオブジェクトが生成されます。 コンテキストマネージャには、
__enter__()
および__exit__()
メソッドが必要です。 - コンテキストマネージャの
__enter__()
メソッドが呼び出されます。 返された値は VAR に割り当てられます。'as VAR'
句が存在しない場合、値は単に破棄されます。 - BLOCK のコードが実行されます。
- BLOCK で例外が発生した場合、
__exit__(type, value, traceback)
が例外の詳細とともに呼び出されます。これは、 sys.exc_info()によって返される値と同じです。 メソッドの戻り値は、例外が再発生するかどうかを制御します。偽の値があると、例外が再発生し、True
によって例外が抑制されます。 ' with 'ステートメントを含むコードの作成者が何かがうまくいかなかったことに気付くことは決してないので、例外を抑制したいと思うことはめったにありません。 - BLOCK で例外が発生しなかった場合でも、
__exit__()
メソッドは呼び出されますが、 type 、 value 、および traceback [ X136X]はすべてNone
です。
例を考えてみましょう。 詳細なコードは示しませんが、トランザクションをサポートするデータベースに必要なメソッドのみをスケッチします。
(データベースの用語に慣れていない人のために:データベースへの一連の変更はトランザクションにグループ化されます。 トランザクションは、すべての変更がデータベースに書き込まれることを意味するコミット、または変更がすべて破棄されてデータベースが変更されないことを意味するロールバックのいずれかです。 詳細については、データベースの教科書を参照してください。)
データベース接続を表すオブジェクトがあると仮定しましょう。 私たちの目標は、ユーザーが次のようなコードを記述できるようにすることです。
db_connection = DatabaseConnection()
with db_connection as cursor:
cursor.execute('insert into ...')
cursor.execute('delete from ...')
# ... more operations ...
ブロック内のコードが問題なく実行された場合はトランザクションをコミットするか、例外がある場合はロールバックする必要があります。 DatabaseConnection
の基本的なインターフェイスは次のとおりです。
class DatabaseConnection:
# Database interface
def cursor (self):
"Returns a cursor object and starts a new transaction"
def commit (self):
"Commits current transaction"
def rollback (self):
"Rolls back current transaction"
__enter__()
メソッドは非常に簡単で、新しいトランザクションを開始するだけで済みます。 このアプリケーションの場合、結果のカーソルオブジェクトは有用な結果になるため、メソッドはそれを返します。 次に、ユーザーはas cursor
を ' with 'ステートメントに追加して、カーソルを変数名にバインドできます。
class DatabaseConnection:
...
def __enter__ (self):
# Code to start a new transaction
cursor = self.cursor()
return cursor
__exit__()
メソッドは、ほとんどの作業を実行する必要があるため、最も複雑です。 メソッドは、例外が発生したかどうかを確認する必要があります。 例外がなかった場合、トランザクションはコミットされます。 例外が発生した場合、トランザクションはロールバックされます。
以下のコードでは、実行は関数の終わりから外れ、デフォルト値のNone
が返されます。 None
はfalseであるため、例外は自動的に再発生します。 必要に応じて、より明示的に、マークされた場所に return ステートメントを追加することもできます。
class DatabaseConnection:
...
def __exit__ (self, type, value, tb):
if tb is None:
# No exception, so commit
self.commit()
else:
# Exception occurred, so rollback.
self.rollback()
# return False
contextlibモジュール
新しい contextlib モジュールは、「 with 」ステートメントで使用するオブジェクトを作成するのに役立ついくつかの関数とデコレータを提供します。
デコレータはcontextmanager()
と呼ばれ、新しいクラスを定義する代わりに、単一のジェネレータ関数を記述できます。 ジェネレータは正確に1つの値を生成する必要があります。 yield までのコードは、__enter__()
メソッドとして実行され、生成される値は、 with [の変数にバインドされるメソッドの戻り値になります。 X184X] 'ステートメントのas
句(ある場合)。 yield の後のコードは、__exit__()
メソッドで実行されます。 ブロックで発生した例外は、yield
ステートメントによって発生します。
前のセクションのデータベースの例は、このデコレータを使用して次のように記述できます。
from contextlib import contextmanager
@contextmanager
def db_transaction (connection):
cursor = connection.cursor()
try:
yield cursor
except:
connection.rollback()
raise
else:
connection.commit()
db = DatabaseConnection()
with db_transaction(db) as cursor:
...
contextlib モジュールには、多数のコンテキストマネージャーを組み合わせたnested(mgr1, mgr2, ...)
関数もあるため、ネストされた ' with 'ステートメントを記述する必要はありません。 この例では、単一の 'with
'ステートメントがデータベーストランザクションを開始し、スレッドロックを取得します。
lock = threading.Lock()
with nested (db_transaction(db), lock) as (cursor, locked):
...
最後に、closing(object)
関数は、変数にバインドできるように object を返し、ブロックの最後でobject.close
を呼び出します。
import urllib, sys
from contextlib import closing
with closing(urllib.urlopen('http://www.yahoo.com')) as f:
for line in f:
sys.stdout.write(line)
も参照してください
- PEP 343 -「with」ステートメント
- グイドヴァンロッサムとニックコグランによって書かれたPEP。 Mike Bland、Guido van Rossum、およびNealNorwitzによって実装されました。 PEPは、「 with 」ステートメント用に生成されたコードを示しています。これは、ステートメントがどのように機能するかを学習するのに役立ちます。
contextlib モジュールのドキュメント。
PEP 352:新しいスタイルのクラスとしての例外
例外クラスは、クラシッククラスだけでなく、新しいスタイルのクラス、組み込みの Exception クラス、およびすべての標準の組み込み例外( NameError 、 ValueError [ X192X]など)が新しいスタイルのクラスになりました。
例外の継承階層が少し再配置されました。 2.5では、継承関係は次のとおりです。
BaseException # New in Python 2.5
|- KeyboardInterrupt
|- SystemExit
|- Exception
|- (all other current built-in exceptions)
この再配置は、プログラムエラーを示すすべての例外をキャッチしたいことが多いために行われました。 ただし、 KeyboardInterrupt および SystemExit はエラーではなく、通常、ユーザーが Control-C を押す、または sysを呼び出すコードなどの明示的なアクションを表します。 exit()。 ベアのexcept:
はすべての例外をキャッチするため、通常、 KeyboardInterrupt と SystemExit をリストして再発生させる必要があります。 通常のパターンは次のとおりです。
try:
...
except (KeyboardInterrupt, SystemExit):
raise
except:
# Log error...
# Continue running program...
Python 2.5では、except Exception
を記述して同じ結果を達成できるようになりました。通常はエラーを示すすべての例外をキャッチしますが、 KeyboardInterrupt と SystemExit はそのままにします。 以前のバージョンと同様に、ベアexcept:
は引き続きすべての例外をキャッチします。
Python 3.0の目標は、例外として発生したクラスを BaseException または BaseException の子孫から派生させることであり、Python2.xシリーズの将来のリリースで施行が開始される可能性があります。この制約。 したがって、今すぐすべての例外クラスを Exception から派生させることをお勧めします。 Python 3.0では、裸のexcept:
フォームを削除することが提案されていますが、Guido vanRossumはこれを行うかどうかを決定していません。
ステートメントraise "Error occurred"
のように、例外として文字列を発生させることはPython 2.5で非推奨になり、警告がトリガーされます。 目的は、いくつかのリリースで文字列例外機能を削除できるようにすることです。
PEP 353:インデックスタイプとしてssize_tを使用する
int の代わりに新しいPy_ssize_t
型定義を使用して、PythonのC APIを広範囲に変更することで、インタープリターは64ビットプラットフォームでより多くのデータを処理できるようになります。 この変更は、32ビットプラットフォームでのPythonの容量には影響しません。
Pythonインタープリターのさまざまな部分が、Cの int 型を使用してサイズまたはカウントを格納しました。 たとえば、リストまたはタプル内のアイテムの数は、 int に格納されていました。 ほとんどの64ビットプラットフォームのCコンパイラは、 int を32ビットタイプとして定義しているため、リストは2**31 - 1
= 2147483647までしか保持できませんでした。 (実際には、64ビットCコンパイラが使用できるプログラミングモデルがいくつかあります。詳細については、 http://www.unix.org/version2/whatsnew/lp64_wp.html を参照してください)が、最も一般的です。使用可能なモデルでは、 int は32ビットのままです。)
長さの制限に達する前にメモリが不足するため、32ビットプラットフォームでは2147483647アイテムの制限は実際には重要ではありません。 各リストアイテムには、4バイトのポインタ用のスペースと、アイテムを表す PyObject 用のスペースが必要です。 2147483647 * 4は、32ビットアドレス空間に含めることができるバイト数をすでに超えています。
ただし、64ビットプラットフォームでその量のメモリに対処することは可能です。 そのサイズのリストへのポインターは16GiBのスペースしか必要としないので、Pythonプログラマーがそのような大きなリストを作成するのは不合理ではありません。 したがって、Pythonインタープリターを int 以外の型を使用するように変更する必要があり、これは64ビットプラットフォームでは64ビット型になります。 この変更により、64ビットマシンで非互換性が発生するため、64ビットユーザーの数はまだ比較的少ないものの、今すぐ移行する価値があると考えられました。 (5年または10年以内に、すべてが64ビットマシン上にある可能性があり、移行はより困難になります。)
この変更は、C拡張モジュールの作成者に最も強く影響します。 Pythonの文字列と、リストやタプルなどのコンテナタイプは、Py_ssize_t
を使用してサイズを格納するようになりました。 PyList_Size()などの関数は、Py_ssize_t
を返すようになりました。 したがって、拡張モジュールのコードでは、一部の変数をPy_ssize_t
に変更する必要がある場合があります。
PyArg_ParseTuple()および Py_BuildValue()関数には、Py_ssize_t
の新しい変換コードn
があります。 PyArg_ParseTuple()のs#
およびt#
は、デフォルトで int を出力しますが、含める前にマクロPY_SSIZE_T_CLEAN
を定義できます。 Python.h
を使用して、Py_ssize_t
を返します。
PEP 353 には、64ビットプラットフォームのサポートについて学習するために拡張機能の作成者が読む必要のある変換ガイドラインに関するセクションがあります。
PEP 357:「__ index__」メソッド
NumPy開発者は、新しい特別なメソッド__index__()
を追加することによってのみ解決できる問題を抱えていました。 [start:stop:step]
のようにスライス表記を使用する場合、 start 、 stop 、および step インデックスの値はすべて整数または長い必要があります整数。 NumPyは、8、16、32、および64ビットの符号なし整数と符号付き整数に対応するさまざまな特殊な整数型を定義しますが、これらの型をスライスインデックスとして使用できることを通知する方法はありませんでした。
スライスでは、既存の__int__()
メソッドを使用することはできません。このメソッドは、整数への強制を実装するためにも使用されるためです。 スライスで__int__()
を使用した場合、浮動小数点数も正当なスライスインデックスになり、これは明らかに望ましくない動作です。
代わりに、__index__()
と呼ばれる新しい特別なメソッドが追加されました。 引数をとらず、使用するスライスインデックスを指定する整数を返します。 例えば:
class C:
def __index__ (self):
return self.value
戻り値は、Python整数または長整数のいずれかである必要があります。 インタプリタは、返されたタイプが正しいことを確認し、この要件が満たされない場合は TypeError を発生させます。
対応するnb_index
スロットがCレベルの PyNumberMethods 構造に追加され、C拡張機能がこのプロトコルを実装できるようになりました。 PyNumber_Index(obj)
を拡張コードで使用して、__index__()
関数を呼び出し、その結果を取得できます。
その他の言語の変更
Python2.5がコアPython言語に加えるすべての変更は次のとおりです。
dict タイプには、キーがディクショナリに含まれていない場合にサブクラスがデフォルト値を提供できるようにするための新しいフックがあります。 キーが見つからない場合は、辞書の
__missing__(key)
メソッドが呼び出されます。 このフックは、 collections モジュールに新しいdefaultdict
クラスを実装するために使用されます。 次の例では、欠落しているキーに対してゼロを返すディクショナリを定義しています。class zerodict (dict): def __missing__ (self, key): return 0 d = zerodict({1:1, 2:2}) print d[1], d[2] # Prints 1, 2 print d[3], d[4] # Prints 0, 0
8ビット文字列とUnicode文字列の両方に、一般的な使用例を簡素化する新しい
partition(sep)
およびrpartition(sep)
メソッドがあります。find(S)
メソッドは、インデックスを取得するためによく使用されます。インデックスは、文字列をスライスし、セパレータの前後にあるピースを取得するために使用されます。partition(sep)
は、このパターンを単一のメソッド呼び出しに凝縮し、セパレーターの前のサブストリング、セパレーター自体、およびセパレーターの後のサブストリングを含む3タプルを返します。 セパレータが見つからない場合、タプルの最初の要素は文字列全体であり、他の2つの要素は空です。rpartition(sep)
も3タプルを返しますが、文字列の末尾から検索を開始します。r
は「リバース」の略です。いくつかの例:
>>> ('http://www.python.org').partition('://') ('http', '://', 'www.python.org') >>> ('file:/usr/share/doc/index.html').partition('://') ('file:/usr/share/doc/index.html', '', '') >>> (u'Subject: a quick question').partition(':') (u'Subject', u':', u' a quick question') >>> 'www.python.org'.rpartition('.') ('www.python', '.', 'org') >>> 'www.python.org'.rpartition(':') ('', '', 'www.python.org')
(Raymond Hettingerの提案に従って、Fredrik Lundhによって実装されました。)
文字列型の
startswith()
およびendswith()
メソッドは、チェックする文字列のタプルを受け入れるようになりました。def is_image_file (filename): return filename.endswith(('.gif', '.jpg', '.tiff'))
(TomLynnの提案に従ってGeorgBrandlによって実装されました。)
min()および max()組み込み関数は、
sort()
のkey
引数に類似したkey
キーワードパラメーターを取得しました。 ]。 このパラメーターは、単一の引数を取り、リスト内のすべての値に対して呼び出される関数を提供します。 min() / max()は、この関数からの戻り値が最小/最大の要素を返します。 たとえば、リスト内で最長の文字列を見つけるには、次のようにします。L = ['medium', 'longest', 'short'] # Prints 'longest' print max(L, key=len) # Prints 'short', because lexicographically 'short' has the largest value print max(L)
(StevenBethardとRaymondHettingerによる寄稿。)
2つの新しい組み込み関数 any()と all()は、イテレーターにtrueまたはfalseの値が含まれているかどうかを評価します。 any()は、イテレータによって返される値がtrueの場合、 True を返します。 それ以外の場合は、 False を返します。 all()は、イテレータによって返されるすべての値がtrueと評価された場合にのみ、 True を返します。 (Guido van Rossumによって提案され、Raymond Hettingerによって実装されました。)
クラスの
__hash__()
メソッドの結果は、長整数または通常の整数のいずれかになります。 長整数が返された場合、その値のハッシュが取得されます。 以前のバージョンでは、ハッシュ値は通常の整数である必要がありましたが、2.5では、 id()組み込みが常に非負の数を返すように変更され、ユーザーはid(self)
(ただし、これは推奨されません)。現在、ASCIIはモジュールのデフォルトのエンコーディングです。 モジュールに8ビット文字の文字列リテラルが含まれているが、エンコーディング宣言がない場合は、構文エラーになります。 Python 2.4では、これにより構文エラーではなく警告がトリガーされました。 モジュールのエンコーディングを宣言する方法については、 PEP 263 を参照してください。 たとえば、ソースファイルの先頭近くに次のような行を追加できます。
# -*- coding: latin1 -*-
Unicode文字列とデフォルトのASCIIエンコーディングを使用してUnicodeに変換できない8ビット文字列を比較しようとすると、新しい警告 UnicodeWarning がトリガーされます。 比較の結果は誤りです。
>>> chr(128) == unichr(128) # Can't convert chr(128) to Unicode __main__:1: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal False >>> chr(127) == unichr(127) # chr(127) can be converted True
以前は、これにより UnicodeDecodeError 例外が発生していましたが、2.5では、辞書にアクセスするときに不可解な問題が発生する可能性がありました。
unichr(128)
を検索し、chr(128)
がキーとして使用されていた場合、 UnicodeDecodeError 例外が発生します。 2.5での他の変更により、辞書を実装するdictobject.c
のコードによって抑制されるのではなく、この例外が発生しました。このような比較の例外を発生させることは厳密に正しいですが、変更によってコードが壊れた可能性があるため、代わりに UnicodeWarning が導入されました。
(Marc-AndréLemburgによって実装されました。)
Pythonプログラマーが時々犯すエラーの1つは、パッケージディレクトリに
__init__.py
モジュールを含めるのを忘れていることです。 この間違いのデバッグは混乱を招く可能性があり、通常、検索されたすべてのパスをログに記録するには、 -v スイッチを指定してPythonを実行する必要があります。 Python 2.5では、インポートでディレクトリがパッケージとして取得されたが、__init__.py
が見つからなかった場合に、新しい ImportWarning 警告がトリガーされます。 この警告はデフォルトでは黙って無視されます。 警告メッセージを表示するためにPython実行可能ファイルを実行するときに、 -Wd オプションを指定します。 (Thomas Woutersによって実装されました。)クラス定義の基本クラスのリストを空にすることができるようになりました。 例として、これは現在合法です:
class C(): pass
(Brett Cannonによって実装されました。)
インタラクティブインタプリタの変更
インタラクティブインタプリタでは、quit
とexit
は長い間文字列であったため、新しいユーザーが終了しようとすると、いくらか役立つメッセージが表示されます。
>>> quit
'Use Ctrl-D (i.e. EOF) to exit.'
Python 2.5では、quit
とexit
は、それ自体の文字列表現を生成するオブジェクトですが、呼び出し可能でもあります。 quit()
またはexit()
を試した初心者は、期待どおりにインタプリタを終了します。 (Georg Brandlによって実装されました。)
Python実行可能ファイルは、標準の長いオプション -help および -version を受け入れるようになりました。 Windowsでは、ヘルプメッセージを表示するための /?オプションも受け入れます。 (Georg Brandlによって実装されました。)
最適化
最適化のいくつかは、2006年5月21日から28日にアイスランドのレイキャビクで開催されたイベントであるNeedForSpeedスプリントで開発されました。 スプリントは、CPython実装の速度向上に焦点を当てており、CCPGamesからのローカルサポートを受けてEWTLLCによって資金提供されました。 このスプリントで追加されたこれらの最適化は、次のリストで特別にマークされています。
- Python 2.4で導入されたとき、組み込みの set および frozenset 型は、Pythonの辞書型の上に構築されていました。 2.5では、内部データ構造はセットを実装するためにカスタマイズされており、その結果、セットは3分の1少ないメモリを使用し、いくらか高速になります。 (Raymond Hettingerによって実装されました。)
- サブ文字列の検索、文字列の分割、文字コード表のエンコードとデコードなど、一部のUnicode操作の速度が向上しました。 (部分文字列検索と分割の改善は、NeedForSpeedスプリントでFredrikLundhとAndrewDalkeによって追加されました。 キャラクターマップはWalterDörwaldとMartinvonLöwisによって改善されました。)
long(str, base)
関数は、計算される中間結果が少なくなるため、長い桁の文字列でより高速になりました。 ピークは、関数が6倍高速な約800〜1000桁の文字列の場合です。 (Alan McIntyreによって寄稿され、NeedForSpeedスプリントでコミットされました。)- ファイルを
for line in file
と繰り返し、ファイルオブジェクトのread()
/ readline() /readlines()
メソッドを呼び出すことは違法になりました。 反復は内部バッファーを使用し、read*()
メソッドはそのバッファーを使用しません。 代わりに、バッファに続いてデータを返すため、データの順序が乱れているように見えます。 反復とこれらのメソッドを混合すると、read*()
メソッドから ValueError がトリガーされるようになりました。 (Thomas Woutersによって実装されました。) - struct モジュールは、構造体フォーマットの文字列を内部表現にコンパイルし、この表現をキャッシュして、20 % s peedupを生成するようになりました。 (NeedForSpeedスプリントでBob Ippolitoによって寄稿されました。)
- re モジュールは、システムの
malloc()
およびfree()
の代わりにPythonのアロケーター関数に切り替えることで、1または2 % sの速度を上げました。 (NeedForSpeedスプリントでJack Diederichによって寄稿されました。) - コードジェネレーターののぞき穴オプティマイザーは、式で単純な定数畳み込みを実行するようになりました。
a = 2+3
のようなものを書くと、コードジェネレーターが計算を行い、a = 5
に対応するコードを生成します。 (Raymond Hettingerによって提案および実装されました。) - コードオブジェクトがコードオブジェクトの内部フィールドに最後に終了したフレーム(「ゾンビフレーム」)を保持し、次にコードオブジェクトが呼び出されたときにそれを再利用するため、関数呼び出しが高速になりました。 (Michael Hudsonによる元のパッチ、ArminRigoとRichardJonesによって変更され、NeedForSpeedスプリントでコミットされました。)フレームオブジェクトもわずかに小さいため、キャッシュの局所性が向上し、メモリ使用量が少し削減される可能性があります。 (Neal Norwitzによる寄稿。)
- Pythonの組み込み例外は、新しいスタイルのクラスになりました。これにより、インスタンス化が大幅に高速化されます。 したがって、Python 2.5での例外処理は、2.4よりも約30 % f asterです。 (NeedForSpeedスプリントでRichard Jones、Georg Brandl、Sean Reifschneiderによって寄稿されました。)
- インポートすると、試行されたパスがキャッシュされ、パスが存在するかどうかが記録されるため、インタプリタは起動時に
open()
およびstat()
の呼び出しを少なくします。 (MartinvonLöwisとGeorg Brandlによる寄稿)
新規、改善、および削除されたモジュール
標準ライブラリは、Python2.5で多くの機能拡張とバグ修正を受けました。 これは、モジュール名のアルファベット順にソートされた、最も注目すべき変更の部分的なリストです。 変更のより完全なリストについては、ソースツリーのMisc/NEWS
ファイルを参照するか、すべての詳細についてSVNログを調べてください。
audioop モジュールがa-LAWエンコーディングをサポートするようになり、u-LAWエンコーディングのコードが改善されました。 (Lars Immischによる寄稿。)
コーデックモジュールは、インクリメンタルコーデックのサポートを取得しました。
codec.lookup()
関数は、タプルではなくCodecInfo
インスタンスを返すようになりました。CodecInfo
インスタンスは、下位互換性を維持するために4タプルのように動作しますが、属性encode
、decode
、incrementalencoder
、incrementaldecoder
、streamwriter
、およびstreamreader
。 インクリメンタルコーデックは、入力を受け取り、複数のチャンクで出力を生成できます。 出力は、入力全体が非インクリメンタルコーデックに供給された場合と同じです。 詳細については、コーデックモジュールのドキュメントを参照してください。 (WalterDörwaldによって設計および実装されました。)collections モジュールは、標準の dict タイプをサブクラス化する新しいタイプ
defaultdict
を取得しました。 新しいタイプはほとんど辞書のように動作しますが、キーが存在しない場合はデフォルト値を作成し、要求されたキー値の辞書に自動的に追加します。defaultdict
のコンストラクターの最初の引数は、キーが要求されたが見つからない場合に呼び出されるファクトリ関数です。 このファクトリ関数は引数を受け取らないため、 list()や int()などの組み込み型コンストラクターを使用できます。 たとえば、次のように頭文字に基づいて単語のインデックスを作成できます。words = """Nel mezzo del cammin di nostra vita mi ritrovai per una selva oscura che la diritta via era smarrita""".lower().split() index = defaultdict(list) for w in words: init_letter = w[0] index[init_letter].append(w)
index
を印刷すると、次の出力が得られます。defaultdict(<type 'list'>, {'c': ['cammin', 'che'], 'e': ['era'], 'd': ['del', 'di', 'diritta'], 'm': ['mezzo', 'mi'], 'l': ['la'], 'o': ['oscura'], 'n': ['nel', 'nostra'], 'p': ['per'], 's': ['selva', 'smarrita'], 'r': ['ritrovai'], 'u': ['una'], 'v': ['vita', 'via']}
(Guido van Rossumによる寄稿。)
collections モジュールによって提供される
deque
両端キュータイプに、キュー内で最初に出現する value を削除するremove(value)
メソッドが追加されました。値が見つからない場合は、 ValueError を発生させます。 (Raymond Hettingerによる寄稿。)新しいモジュール: contextlib モジュールには、新しい ' with 'ステートメントで使用するヘルパー関数が含まれています。 このモジュールの詳細については、セクション contextlibモジュールを参照してください。
新しいモジュール: cProfile モジュールは、既存の profile モジュールのC実装であり、オーバーヘッドがはるかに低くなっています。 モジュールのインターフェースは profile と同じです。
cProfile.run('main()')
を実行して関数のプロファイルを作成したり、プロファイルデータをファイルに保存したりできます。 同じくCで記述されているが、 profile モジュールのインターフェースと一致しないHotshotプロファイラーが、Pythonの将来のバージョンで引き続き維持されるかどうかはまだわかりません。 (Armin Rigoによる寄稿。)また、プロファイラーによって測定されたデータを分析するための pstats モジュールは、 stream 引数を
Stats
コンストラクターに提供することにより、任意のファイルオブジェクトへの出力の送信をサポートするようになりました。 (Skip Montanaroによる寄稿。)ファイルをコンマ区切り値形式で解析する csv モジュールには、いくつかの機能強化といくつかのバグ修正が含まれていました。
csv.field_size_limit(new_limit)
関数を呼び出すことにより、フィールドの最大サイズをバイト単位で設定できるようになりました。 new_limit 引数を省略すると、現在設定されている制限が返されます。reader
クラスに、ソースから読み取られた物理行の数をカウントするline_num
属性が追加されました。 レコードは複数の物理行にまたがることができるため、line_num
は読み取られるレコードの数と同じではありません。CSVパーサーは、複数行の引用符で囲まれたフィールドについてより厳密になりました。 以前は、改行文字を終了せずに引用符で囲まれたフィールド内で行が終了した場合、返されたフィールドに改行が挿入されていました。 この動作により、フィールド内にキャリッジリターン文字を含むファイルを読み取るときに問題が発生したため、改行を挿入せずにフィールドを返すようにコードが変更されました。 結果として、フィールド内に埋め込まれた改行が重要である場合、入力は改行文字を保持する方法で行に分割する必要があります。
(SkipMontanaroとAndrewMcNamaraによる寄稿。)
datetime モジュールの datetime クラスに、JoshSpoerriによって提供された日付文字列を解析するための
strptime(string, format)
メソッドが追加されました。 time.strptime()および time.strftime()と同じフォーマット文字を使用します。from datetime import datetime ts = datetime.strptime('10:13:15 2006-03-07', '%H:%M:%S %Y-%m-%d')
difflib モジュールの
SequenceMatcher.get_matching_blocks()
メソッドは、一致するサブシーケンスを記述するブロックの最小リストを返すことを保証するようになりました。 以前は、アルゴリズムが一致する要素のブロックを2つのリストエントリに分割することがありました。 (Tim Petersによる拡張。)doctest モジュールは、例がまったく実行されないようにする
SKIP
オプションを取得しました。 これは、読者を対象とした使用例であり、実際にはテストケースではないコードスニペットを対象としています。encoding パラメーターが
testfile()
関数とDocFileSuite
クラスに追加され、ファイルのエンコーディングを指定しました。 これにより、docstring内に含まれるテストで非ASCII文字を簡単に使用できるようになります。 (Bjorn Tilleniusによる寄稿。)email パッケージがバージョン4.0に更新されました。 (Barry Warsawによる寄稿。)
fileinput モジュールがより柔軟になりました。 Unicodeファイル名がサポートされるようになり、
"r"
にデフォルト設定される mode パラメーターが input()関数に追加され、バイナリまたはユニバーサルでファイルを開くことができるようになりました。 newlines モード。 もう1つの新しいパラメーター openhook を使用すると、 open()以外の関数を使用して入力ファイルを開くことができます。 ファイルのセットを反復処理すると、FileInput
オブジェクトの新しいfileno()
は、現在開いているファイルのファイル記述子を返します。 (Georg Brandlによる寄稿)gc モジュールでは、新しい
get_count()
関数は、3つのGC世代の現在のコレクションカウントを含む3タプルを返します。 これは、ガベージコレクターのアカウンティング情報です。 これらのカウントが指定されたしきい値に達すると、ガベージコレクションのスイープが行われます。 既存の gc.collect()関数は、収集する世代を指定するために、オプションの Generation 引数0、1、または2を受け取るようになりました。 (Barry Warsawによる寄稿。)heapq モジュールの
nsmallest()
およびnlargest()
関数は、 min()[によって提供されるものと同様のkey
キーワードパラメーターをサポートするようになりました。 X155X] / max()関数およびsort()
メソッド。 例えば:>>> import heapq >>> L = ["short", 'medium', 'longest', 'longer still'] >>> heapq.nsmallest(2, L) # Return two lowest elements, lexicographically ['longer still', 'longest'] >>> heapq.nsmallest(2, L, key=len) # Return two shortest elements ['short', 'medium']
(Raymond Hettingerによる寄稿。)
itertools.islice()関数は、開始引数とステップ引数に
None
を受け入れるようになりました。 これにより、スライスオブジェクトの属性との互換性が高まり、次のように記述できるようになります。s = slice(5) # Create slice object itertools.islice(iterable, s.start, s.stop, s.step)
(Raymond Hettingerによる寄稿。)
locale モジュールの format()関数が変更され、
format_string()
とcurrency()
の2つの新しい関数が追加されました。format()関数の val パラメーターは、%c har指定子が1つしか出現しない限り、以前は文字列でした。 ここで、パラメーターは、周囲のテキストを含まない、正確に1つの%c har指定子である必要があります。 オプションの monetary パラメーターも追加されました。これは、
True
の場合、3桁のグループ間に区切り文字を配置する際に通貨をフォーマットするためのロケールの規則を使用します。複数の%c har指定子を使用して文字列をフォーマットするには、 format()と同様に機能するが、%c har指定子と任意のテキストの混合もサポートする新しい
format_string()
関数を使用します。現在のロケールの設定に従って数値をフォーマットする新しい
currency()
関数も追加されました。(Georg Brandlによる寄稿)
mailbox モジュールは、メールボックスの読み取りに加えてメールボックスを変更する機能を追加するために大規模な書き直しが行われました。
mbox
、MH
、およびMaildir
を含む新しいクラスのセットは、メールボックスの読み取りに使用され、add(message)
メソッドを使用してメッセージを追加します[X144X ] はメッセージを削除し、lock()
/unlock()
はメールボックスをロック/ロック解除します。 次の例では、maildir形式のメールボックスをmbox形式のメールボックスに変換します。import mailbox # 'factory=None' uses email.Message.Message as the class representing # individual messages. src = mailbox.Maildir('maildir', factory=None) dest = mailbox.mbox('/tmp/mbox') for msg in src: dest.add(msg)
(GregoryKによる寄稿。 ジョンソン。 資金はGoogleの2005Summer of Codeによって提供されました。)
新しいモジュール: msilib モジュールを使用すると、Microsoftインストーラー
.msi
ファイルとCABファイルを作成できます。.msi
データベースを読み取るためのサポートも含まれています。 (MartinvonLöwisによる寄稿。)nis モジュールは、 nis.match()および nis.mapsに domain 引数を指定することにより、システムのデフォルトドメイン以外のドメインへのアクセスをサポートするようになりました。 ()関数。 (Ben Bellによる寄稿。)
operator モジュールの
itemgetter()
およびattrgetter()
関数は、複数のフィールドをサポートするようになりました。operator.attrgetter('a', 'b')
などの呼び出しは、a
およびb
属性を取得する関数を返します。 この新機能をsort()
メソッドのkey
パラメーターと組み合わせると、複数のフィールドを使用してリストを簡単に並べ替えることができます。 (Raymond Hettingerによる寄稿。)optparse モジュールがOptikライブラリのバージョン1.5.1に更新されました。
OptionParser
クラスは、epilog
属性、ヘルプメッセージの後に出力される文字列、およびオブジェクトによって作成された参照サイクルを中断するdestroy()
メソッドを取得しました。 (Greg Wardによる寄稿)os モジュールにはいくつかの変更が加えられました。
stat_float_times
変数はデフォルトでtrueになりました。これは、 os.stat()が時間値を浮動小数点数として返すことを意味します。 (これは、 os.stat()が数分の1秒の精度で時間を返すことを必ずしも意味しません。すべてのシステムがそのような精度をサポートしているわけではありません。)os.SEEK_SET 、 os.SEEK_CUR 、および os.SEEK_END という名前の定数が追加されました。 これらは、 os.lseek()関数のパラメーターです。 ロック用の2つの新しい定数は、 os.O_SHLOCK と os.O_EXLOCK です。
wait3()
とwait4()
の2つの新機能が追加されました。 これらは、子プロセスが終了するのを待ってプロセスIDとその終了ステータスのタプルを返すwaitpid()
関数に似ていますが、wait3()
とwait4()
は追加情報を返します。wait3()
はプロセスIDを入力として受け取らないため、子プロセスが終了するのを待ち、 process-id 、 exit-status の3タプルを返します。 ]、 resource.getrusage()関数から返される resource-usage 。wait4(pid)
はプロセスIDを取ります。 (ChadJによる寄稿。 シュローダー。)FreeBSDでは、 os.stat()関数がナノ秒の解像度で時間を返すようになり、返されるオブジェクトには
st_gen
とst_birthtime
が含まれるようになりました。 プラットフォームがサポートしている場合は、st_flags
属性も使用できます。 (Antti LoukoとDiegoPettenòによる寄稿)pdb モジュールによって提供されるPythonデバッガーは、ブレークポイントに到達して実行が停止したときに実行するコマンドのリストを格納できるようになりました。 ブレークポイント#1が作成されたら、
commands 1
と入力し、実行する一連のコマンドを入力して、リストをend
で終了します。 コマンドリストには、continue
やnext
などの実行を再開するコマンドを含めることができます。 (GrégoireDoomsによる寄稿。)pickle および
cPickle
モジュールは、__reduce__()
メソッドからのNone
の戻り値を受け入れなくなりました。 メソッドは、代わりに引数のタプルを返す必要があります。None
を返す機能は、Python 2.4で非推奨になったため、この機能の削除は完了です。パッケージを検索するためのさまざまなユーティリティ関数を含む pkgutil モジュールは、 PEP 302 のインポートフックをサポートするように拡張され、ZIP-に保存されたパッケージでも機能するようになりました。フォーマットアーカイブ。 (PhillipJによる寄稿。 Eby。)
Marc-AndréLemburgによるpybenchベンチマークスイートが
Tools/pybench
ディレクトリに含まれるようになりました。 pybenchは、通訳者の速度のより詳細な測定を提供するため、一般的に使用されるpystone.py
プログラムを改良したものです。pystone.py
のように多くの異なる操作を実行して結果を単一の数値に減らすのではなく、関数呼び出し、タプルスライス、メソッドルックアップ、数値操作などの特定の操作の時間を計測します。pyexpat
モジュールは、バージョン2.0のExpatパーサーを使用するようになりました。 (Trent Mickによる寄稿。)Queue
モジュールによって提供される Queue クラスには、2つの新しいメソッドが追加されました。join()
は、キュー内のすべてのアイテムが取得され、アイテムのすべての処理作業が完了するまでブロックします。 ワーカースレッドは、もう1つの新しいメソッドtask_done()
を呼び出して、アイテムの処理が完了したことを通知します。 (Raymond Hettingerによる寄稿。)Python2.0以降廃止された古い
regex
およびregsub
モジュールは、ついに削除されました。 その他の削除されたモジュール:statcache
、tzparse
、whrandom
。また、削除されました。
dircmp
やni
などの古いモジュールを含むlib-old
ディレクトリが削除されました。lib-old
はデフォルトのsys.path
になかったため、プログラムがディレクトリをsys.path
に明示的に追加しない限り、この削除がコードに影響を与えることはありません。rlcompleter モジュールは、 readline モジュールのインポートに依存しなくなったため、Unix以外のプラットフォームで動作するようになりました。 (Robert Kiendlからのパッチ。)
SimpleXMLRPCServer
クラスとDocXMLRPCServer
クラスに、XML-RPC操作を制限されたURLパスのセットに制限するrpc_paths
属性が追加されました。 デフォルトでは、'/'
と'/RPC2'
のみが許可されます。rpc_paths
をNone
に設定するか、タプルを空にすると、このパスチェックが無効になります。socket モジュールは、Philippe Biondiからのパッチのおかげで、Linuxで
AF_NETLINK
ソケットをサポートするようになりました。 Netlinkソケットは、ユーザースペースプロセスとカーネルコード間の通信のためのLinux固有のメカニズムです。 それらに関する紹介記事は https://www.linuxjournal.com/article/7356 にあります。 Pythonコードでは、ネットリンクアドレスは2つの整数のタプル(pid, group_mask)
として表されます。ソケットオブジェクトの2つの新しいメソッド
recv_into(buffer)
とrecvfrom_into(buffer)
は、データを文字列として返す代わりに、バッファプロトコルをサポートするオブジェクトに受信データを格納します。 これは、データを配列またはメモリマップトファイルに直接配置できることを意味します。ソケットオブジェクトは、ソケットのファミリ、タイプ、およびプロトコル値を取得するために、
getfamily()
、gettype()
、およびgetproto()
アクセサメソッドも取得しました。新しいモジュール: spwd モジュールは、シャドウパスワードをサポートするシステム上のシャドウパスワードデータベースにアクセスするための関数を提供します。
struct は、
pack()
およびunpack()
メソッドを使用してフォーマット文字列をStruct
オブジェクトにコンパイルするため、より高速になりました。 これは、 re モジュールでコンパイル済みの正規表現オブジェクトを作成する方法と似ています。 モジュールレベルのpack()
およびunpack()
関数は引き続き使用できます。Struct
オブジェクトを作成し、それらをキャッシュします。 または、Struct
インスタンスを直接使用できます。s = struct.Struct('ih3s') data = s.pack(1972, 187, 'abc') year, number, name = s.unpack(data)
pack_into(buffer, offset, v1, v2, ...)
およびunpack_from(buffer, offset)
メソッドを使用して、バッファーオブジェクトとの間でデータを直接パックおよびアンパックすることもできます。 これにより、データを配列またはメモリマップファイルに直接保存できます。(
Struct
オブジェクトは、NeedForSpeedスプリントでBobIppolitoによって実装されました。 バッファオブジェクトのサポートは、同じくNeedForSpeedスプリントでMartin Blaisによって追加されました。)Python開発者は、2.5の開発プロセス中にCVSからSubversionに切り替えました。 正確なビルドバージョンに関する情報は、
sys.subversion
変数、(interpreter-name, branch-name, revision-range)
の3タプルとして入手できます。 たとえば、これを書いている時点で、私の2.5のコピーは('CPython', 'trunk', '45313:45315')
を報告していました。この情報は、 Py_GetBuildInfo()関数を介してC拡張機能でも利用できます。この関数は、
"trunk:45355:45356M, Apr 13 2006, 07:42:19"
のようなビルド情報の文字列を返します。 (Barry Warsawによる寄稿。)別の新しい関数 sys._current_frames()は、実行中のすべてのスレッドの現在のスタックフレームを、関数が呼び出されたときにそのスレッドで現在アクティブな最上位のスタックフレームにスレッド識別子をマッピングするディクショナリとして返します。 (Tim Petersによる寄稿。)
tarfile モジュールの
TarFile
クラスに、アーカイブから現在の作業ディレクトリにすべてのメンバーを抽出するextractall()
メソッドが追加されました。 抽出ターゲットとして別のディレクトリを設定し、アーカイブのメンバーのサブセットのみを解凍することもできます。ストリームモードで開かれたtarfileに使用される圧縮は、モード
'r|*'
を使用して自動検出できるようになりました。 (LarsGustäbelによる寄稿。)threading モジュールで、新しいスレッドの作成時に使用されるスタックサイズを設定できるようになりました。
stack_size([*size*])
関数は、現在構成されているスタックサイズを返し、オプションの size パラメーターを指定すると新しい値が設定されます。 すべてのプラットフォームがスタックサイズの変更をサポートしているわけではありませんが、Windows、POSIXスレッド、およびOS / 2はすべてサポートしています。 (Andrew MacIntyreによる寄稿。)unicodedata モジュールは、Unicode文字データベースのバージョン4.1.0を使用するように更新されました。 一部の仕様ではバージョン3.2.0が必要であるため、 unicodedata.ucd_3_2_0 として引き続き利用できます。
新しいモジュール: uuid モジュールは、 RFC 4122 に従って、ユニバーサル一意識別子(UUID)を生成します。 RFCは、開始文字列から、システムプロパティから、または純粋にランダムに生成されるいくつかの異なるUUIDバージョンを定義します。 このモジュールには、
UUID
クラスと、uuid1()
、uuid3()
、uuid4()
、およびuuid5()
という名前の関数が含まれており、さまざまなバージョンのUUIDを生成します。 (バージョン2のUUIDは RFC 4122 で指定されておらず、このモジュールではサポートされていません。)>>> import uuid >>> # make a UUID based on the host ID and current time >>> uuid.uuid1() UUID('a8098c1a-f86e-11da-bd1a-00112444be1e') >>> # make a UUID using an MD5 hash of a namespace UUID and a name >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org') UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e') >>> # make a random UUID >>> uuid.uuid4() UUID('16fd2706-8baf-433b-82eb-8c7fada847da') >>> # make a UUID using a SHA-1 hash of a namespace UUID and a name >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org') UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
(Ka-Ping Yeeによる寄稿。)
weakref モジュールの
WeakKeyDictionary
およびWeakValueDictionary
タイプは、ディクショナリに含まれる弱参照を反復処理するための新しいメソッドを取得しました。iterkeyrefs()
およびkeyrefs()
メソッドがWeakKeyDictionary
に追加され、itervaluerefs()
およびvaluerefs()
がWeakValueDictionary
に追加されました。 (FredLによる寄稿。 ドレイクジュニア)webbrowser モジュールは多くの機能強化を受けました。 URLを引数として
python -m webbrowser
のスクリプトとして使用できるようになりました。 動作を制御するためのスイッチがいくつかあります(新しいブラウザウィンドウの場合は-n
、新しいタブの場合は-t
)。 これをサポートするために、新しいモジュールレベルの関数open_new()
およびopen_new_tab()
が追加されました。 モジュールの open()関数は、追加機能である autoraise パラメーターをサポートし、可能な場合に開いているウィンドウを上げるかどうかを通知します。 Firefox、Opera、Konqueror、elinksなど、多数の追加ブラウザがサポートリストに追加されました。 (OlegBroytmannとGeorgBrandlによる寄稿)xmlrpclib
モジュールは、XML-RPC日付型の datetime オブジェクトの戻りをサポートするようになりました。use_datetime=True
をloads()
関数またはUnmarshaller
クラスに指定して、この機能を有効にします。 (Skip Montanaroによる寄稿。)zipfile モジュールは、ZIP64バージョンの形式をサポートするようになりました。つまり、.zipアーカイブは4 GiBより大きくなり、4GiBより大きい個々のファイルを含めることができます。 (Ronald Oussorenによる寄稿。)
zlib モジュールの
Compress
およびDecompress
オブジェクトは、オブジェクトの内部状態のコピーを作成して新しい[ X165X] またはDecompress
オブジェクト。 (Chris AtLeeによる寄稿。)
ctypesパッケージ
ThomasHellerによって書かれた ctypes パッケージが標準ライブラリに追加されました。 ctypes を使用すると、共有ライブラリまたはDLL内の任意の関数を呼び出すことができます。 長年のユーザーは、dl
モジュールを覚えているかもしれません。このモジュールは、共有ライブラリをロードして関数を呼び出すための関数を提供します。 ctypes パッケージははるかに魅力的です。
共有ライブラリまたはDLLをロードするには、CDLL
クラスのインスタンスを作成し、共有ライブラリまたはDLLの名前またはパスを指定する必要があります。 それが完了したら、CDLL
オブジェクトの属性としてそれらにアクセスすることにより、任意の関数を呼び出すことができます。
import ctypes
libc = ctypes.CDLL('libc.so.6')
result = libc.printf("Line of output\n")
さまざまなC型の型構築子が提供されています:c_int()
、c_float()
、c_double()
、c_char_p()
( char * と同等)、などなど。 Pythonのタイプとは異なり、Cバージョンはすべて変更可能です。 value
属性に割り当てて、ラップされた値を変更できます。 Pythonの整数と文字列は、対応するC型に自動的に変換されますが、他の型の場合は、正しい型コンストラクターを呼び出す必要があります。 (つまり、 must です。間違えると、セグメンテーション違反でインタープリターがクラッシュすることがよくあります。)
Python文字列は不変であると想定されているため、C関数がメモリ領域を変更する場合は、Python文字列でc_char_p()
を使用しないでください。 このルールに違反すると、不可解なバグが発生します。 変更可能なメモリ領域が必要な場合は、create_string_buffer()
を使用してください。
s = "this is a string"
buf = ctypes.create_string_buffer(s)
libc.strfry(buf)
C関数は整数を返すと想定されていますが、関数オブジェクトのrestype
属性を設定して、これを変更できます。
>>> libc.atof('2.71828')
-1783957616
>>> libc.atof.restype = ctypes.c_double
>>> libc.atof('2.71828')
2.71828
ctypes は、PythonのCAPIのラッパーをctypes.pythonapi
オブジェクトとして提供します。 このオブジェクトは、関数を呼び出す前にグローバルインタープリターロックを解放しません。インタープリターのコードを呼び出すときにロックを保持する必要があるためです。 PyObject * ポインターを作成するpy_object()
型コンストラクターがあります。 簡単な使用法:
import ctypes
d = {}
ctypes.pythonapi.PyObject_SetItem(ctypes.py_object(d),
ctypes.py_object("abc"), ctypes.py_object(1))
# d is now {'abc', 1}.
py_object()
を使用することを忘れないでください。 省略した場合、セグメンテーション違反が発生します。
ctypes はしばらく前から存在していますが、 ctypes の存在に頼ることができないため、人々は依然として手書きの拡張モジュールを作成して配布しています。 おそらく開発者は、 ctypes がコアPythonに含まれているので、拡張モジュールではなく ctypes を介してアクセスされるライブラリの上にPythonラッパーを書き始めるでしょう。
も参照してください
- http://starship.python.net/crew/theller/ctypes/
- チュートリアル、リファレンス、FAQを含むctypesWebページ。
ctypes モジュールのドキュメント。
ElementTreeパッケージ
XMLを処理するためのFredrikLundhのElementTreeライブラリのサブセットが、xml.etree
として標準ライブラリに追加されました。 使用可能なモジュールは、ElementTree1.2.6のElementTree
、ElementPath
、およびElementInclude
です。 cElementTree
アクセラレータモジュールも含まれています。
このセクションの残りの部分では、ElementTreeの使用の概要を説明します。 ElementTreeの完全なドキュメントは、 http://effbot.org/zone/element-index.htmで入手できます。
ElementTreeは、XMLドキュメントを要素ノードのツリーとして表します。 ドキュメントのテキストコンテンツは、text
およびtail
属性として保存されます(これは、ElementTreeとドキュメントオブジェクトモデルの主な違いの1つです。DOMには、さまざまなタイプのタイプがあります。 TextNode
を含むノード。)
最も一般的に使用される解析関数はparse()
で、文字列(ファイル名を含むと想定)またはファイルのようなオブジェクトを受け取り、ElementTree
インスタンスを返します。
from xml.etree import ElementTree as ET
tree = ET.parse('ex-1.xml')
feed = urllib.urlopen(
'http://planet.python.org/rss10.xml')
tree = ET.parse(feed)
ElementTree
インスタンスを作成したら、そのgetroot()
メソッドを呼び出して、ルートElement
ノードを取得できます。
文字列リテラルを受け取り、Element
ノード(ElementTree
ではない)を返すXML()
関数もあります。 この関数は、XMLフラグメントを組み込むための整然とした方法を提供し、XMLリテラルの利便性に近づきます。
svg = ET.XML("""<svg width="10px" version="1.0">
</svg>""")
svg.set('height', '320px')
svg.append(elem1)
各XML要素は、辞書のようなアクセス方法とリストのようなアクセス方法をサポートしています。 辞書のような操作は属性値にアクセスするために使用され、リストのような操作は子ノードにアクセスするために使用されます。
手術 | 結果 |
---|---|
elem[n]
|
n番目の子要素を返します。 |
elem[m:n]
|
m番目からn番目の子要素のリストを返します。 |
len(elem)
|
子要素の数を返します。 |
list(elem)
|
子要素のリストを返します。 |
elem.append(elem2)
|
elem2 を子として追加します。 |
elem.insert(index, elem2)
|
指定した場所に elem2 を挿入します。 |
del elem[n]
|
n番目の子要素を削除します。 |
elem.keys()
|
属性名のリストを返します。 |
elem.get(name)
|
属性 name の値を返します。 |
elem.set(name, value)
|
属性 name に新しい値を設定します。 |
elem.attrib
|
属性を含む辞書を取得します。 |
del elem.attrib[name]
|
属性名前を削除します。 |
コメントと処理命令もElement
ノードとして表されます。 ノードがコメントまたは処理命令であるかどうかを確認するには、次のようにします。
if elem.tag is ET.Comment:
...
elif elem.tag is ET.ProcessingInstruction:
...
XML出力を生成するには、ElementTree.write()
メソッドを呼び出す必要があります。 parse()
と同様に、文字列またはファイルのようなオブジェクトのいずれかを取ることができます。
# Encoding is US-ASCII
tree.write('output.xml')
# Encoding is UTF-8
f = open('output.xml', 'w')
tree.write(f, encoding='utf-8')
(注意:出力に使用されるデフォルトのエンコーディングはASCIIです。 要素の名前に任意のUnicode文字が含まれる可能性がある一般的なXML作業の場合、ASCIIは、要素の名前に127より大きい値の文字が含まれていると例外が発生するため、あまり有用なエンコーディングではありません。 したがって、任意のUnicode文字を処理できるUTF-8などの別のエンコーディングを指定することをお勧めします。)
このセクションは、ElementTreeインターフェースの部分的な説明にすぎません。 詳細については、パッケージの公式ドキュメントをお読みください。
hashlibパッケージ
GregoryPによって書かれた新しい hashlib モジュール。 md5
およびsha
モジュールを置き換えるためにSmithが追加されました。 hashlib は、追加のセキュアハッシュ(SHA-224、SHA-256、SHA-384、およびSHA-512)のサポートを追加します。 利用可能な場合、モジュールはOpenSSLを使用して、プラットフォームに最適化されたアルゴリズムの実装を高速化します。
古いmd5
およびsha
モジュールは、下位互換性を維持するために、hashlibのラッパーとして引き続き存在します。 新しいモジュールのインターフェースは古いモジュールのインターフェースに非常に近いですが、同一ではありません。 最も重要な違いは、新しいハッシュオブジェクトを作成するためのコンストラクター関数の名前が異なることです。
# Old versions
h = md5.md5()
h = md5.new()
# New version
h = hashlib.md5()
# Old versions
h = sha.sha()
h = sha.new()
# New version
h = hashlib.sha1()
# Hash that weren't previously available
h = hashlib.sha224()
h = hashlib.sha256()
h = hashlib.sha384()
h = hashlib.sha512()
# Alternative form
h = hashlib.new('md5') # Provide algorithm as a string
ハッシュオブジェクトが作成されると、そのメソッドは以前と同じになります。update(string)
は指定された文字列を現在のダイジェスト状態にハッシュし、digest()
とhexdigest()
はダイジェスト値を次のように返します。バイナリ文字列または16進数の文字列であり、 copy()は、同じダイジェスト状態の新しいハッシュオブジェクトを返します。
sqlite3パッケージ
SQLite組み込みデータベースのラッパーであるpysqliteモジュール( http://www.pysqlite.org )が、パッケージ名 sqlite3 で標準ライブラリに追加されました。
SQLiteは、個別のサーバープロセスを必要とせず、SQLクエリ言語の非標準バリアントを使用してデータベースにアクセスできる軽量のディスクベースのデータベースを提供するCライブラリです。 一部のアプリケーションは、内部データストレージにSQLiteを使用できます。 SQLiteを使用してアプリケーションのプロトタイプを作成し、そのコードをPostgreSQLやOracleなどのより大きなデータベースに移植することもできます。
pysqliteはGerhardHäringによって作成され、 PEP 249 で説明されているDB-API2.0仕様に準拠したSQLインターフェイスを提供します。
Pythonソースを自分でコンパイルする場合は、ソースツリーにSQLiteコードは含まれず、ラッパーモジュールのみが含まれることに注意してください。 Pythonをコンパイルする前にSQLiteライブラリとヘッダーをインストールする必要があります。ビルドプロセスは、必要なヘッダーが利用可能になったときにモジュールをコンパイルします。
モジュールを使用するには、最初にデータベースを表すConnection
オブジェクトを作成する必要があります。 ここで、データは/tmp/example
ファイルに保存されます。
conn = sqlite3.connect('/tmp/example')
特別な名前:memory:
を指定して、RAMにデータベースを作成することもできます。
Connection
を取得したら、Cursor
オブジェクトを作成し、そのexecute()
メソッドを呼び出してSQLコマンドを実行できます。
c = conn.cursor()
# Create table
c.execute('''create table stocks
(date text, trans text, symbol text,
qty real, price real)''')
# Insert a row of data
c.execute("""insert into stocks
values ('2006-01-05','BUY','RHAT',100,35.14)""")
通常、SQL操作ではPython変数の値を使用する必要があります。 安全ではないため、Pythonの文字列操作を使用してクエリをアセンブルしないでください。 プログラムがSQLインジェクション攻撃に対して脆弱になります。
代わりに、DB-APIのパラメーター置換を使用してください。 値を使用する場所に?
をプレースホルダーとして配置し、カーソルのexecute()
メソッドの2番目の引数として値のタプルを指定します。 (他のデータベースモジュールは、%s
や:1
などの異なるプレースホルダーを使用する場合があります。)例:
# Never do this -- insecure!
symbol = 'IBM'
c.execute("... where symbol = '%s'" % symbol)
# Do this instead
t = (symbol,)
c.execute('select * from stocks where symbol=?', t)
# Larger example
for t in (('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00),
('2006-04-06', 'SELL', 'IBM', 500, 53.00),
):
c.execute('insert into stocks values (?,?,?,?,?)', t)
SELECTステートメントの実行後にデータを取得するには、カーソルをイテレータとして扱うか、カーソルのfetchone()
メソッドを呼び出して一致する単一の行を取得するか、fetchall()
を呼び出してリストを取得します。一致する行。
この例では、イテレータ形式を使用しています。
>>> c = conn.cursor()
>>> c.execute('select * from stocks order by price')
>>> for row in c:
... print row
...
(u'2006-01-05', u'BUY', u'RHAT', 100, 35.140000000000001)
(u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)
(u'2006-04-06', u'SELL', u'IBM', 500, 53.0)
(u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0)
>>>
SQLiteでサポートされているSQLダイアレクトの詳細については、 https://www.sqlite.org を参照してください。
も参照してください
- http://www.pysqlite.org
- pysqliteのWebページ。
- https://www.sqlite.org
- SQLiteWebページ。 ドキュメントには、サポートされているSQLダイアレクトの構文と使用可能なデータ型が記載されています。
sqlite3 モジュールのドキュメント。
- PEP 249 -データベースAPI仕様2.0
- Marc-AndréLemburgによって書かれたPEP。
wsgirefパッケージ
Webサーバーゲートウェイインターフェイス(WSGI)v1.0は、WebサーバーとPython Webアプリケーション間の標準インターフェイスを定義し、 PEP 333 で説明されています。 wsgiref パッケージは、WSGI仕様のリファレンス実装です。
このパッケージには、WSGIアプリケーションを実行する基本的なHTTPサーバーが含まれています。 このサーバーはデバッグには役立ちますが、実稼働での使用を目的としたものではありません。 サーバーのセットアップには、数行のコードしか必要ありません。
from wsgiref import simple_server
wsgi_app = ...
host = ''
port = 8000
httpd = simple_server.make_server(host, port, wsgi_app)
httpd.serve_forever()
も参照してください
- http://www.wsgi.org
- WSGI関連のリソースの中央Webサイト。
- PEP 333 -PythonWebサーバーゲートウェイインターフェイスv1.0
- フィリップJによって書かれたPEP。 エビー。
ビルドとCAPIの変更
PythonのビルドプロセスとCAPIへの変更は次のとおりです。
Pythonソースツリーは、MartinvonLöwisによって監視され、完璧に実行された複雑な移行手順で、CVSからSubversionに変換されました。 この手順は、 PEP 347 として開発されました。
Preventと呼ばれるソースコード分析ツールを販売しているCoverityは、Pythonソースコードの調査結果を提供しました。 分析により、すぐに修正された約60のバグが見つかりました。 バグの多くは問題を再カウントしており、エラー処理コードで頻繁に発生していました。 統計については、 https://scan.coverity.com を参照してください。
C APIへの最大の変更は、 PEP 353 からのもので、 int の代わりに
Py_ssize_t
型定義を使用するようにインタープリターを変更します。 この変更の説明については、前のセクション PEP 353:インデックスタイプとしてのssize_tの使用を参照してください。バイトコードコンパイラの設計は大幅に変更され、解析ツリーをトラバースしてバイトコードを生成しなくなりました。 代わりに、解析ツリーは抽象構文ツリー(またはAST)に変換され、バイトコードを生成するためにトラバースされるのは抽象構文ツリーです。
compile()組み込みを使用し、 flags パラメーターの値として
_ast.PyCF_ONLY_AST
を指定することにより、PythonコードでASTオブジェクトを取得できます。from _ast import PyCF_ONLY_AST ast = compile("""a=0 for i in range(10): a += i """, "<string>", 'exec', PyCF_ONLY_AST) assignment = ast.body[0] for_loop = ast.body[1]
ASTコードの公式ドキュメントはまだ作成されていませんが、 PEP 339 で設計について説明しています。 コードの学習を開始するには、
Parser/Python.asdl
のさまざまなASTノードの定義をお読みください。 Pythonスクリプトがこのファイルを読み取り、Include/Python-ast.h
に一連のC構造体定義を生成します。Include/pythonrun.h
で定義されているPyParser_ASTFromString()
とPyParser_ASTFromFile()
は、Pythonソースを入力として受け取り、コンテンツを表すASTのルートを返します。 このASTは、PyAST_Compile()
によってコードオブジェクトに変換できます。 詳細については、ソースコードを読んでから、python-devで質問してください。ASTコードは、Jeremy Hyltonの管理下で開発され、Brett Cannon、Nick Coghlan、Grant Edwards、John Ehresman、Kurt Kaiser、Neal Norwitz、Tim Peters、Armin Rigo、Neil Schemenauer、およびPyConなどの会議でのASTスプリントの数。
PyCon DC 2005での講演で最初に説明された、obmallocに対するEvanJonesのパッチが適用されました。 Python 2.4は、256Kサイズのアリーナに小さなオブジェクトを割り当てましたが、アリーナを解放することはありませんでした。 このパッチを使用すると、Pythonはアリーナが空になったときにアリーナを解放します。 正味の効果は、一部のプラットフォームでは、多くのオブジェクトを割り当てると、それらを削除するとPythonのメモリ使用量が実際に低下し、メモリがオペレーティングシステムに戻される可能性があることです。 (Evan Jonesによって実装され、Tim Petersによって作り直されました。)
この変更は、メモリを割り当てるときに拡張モジュールがより注意する必要があることを意味することに注意してください。 PythonのAPIには、ファミリにグループ化されたメモリを割り当てるためのさまざまな関数があります。 たとえば、 PyMem_Malloc()、 PyMem_Realloc()、および PyMem_Free()は、rawメモリを割り当てる1つのファミリですが、 PyObject_Malloc()[X159X ]、 PyObject_Realloc()、および PyObject_Free()は、Pythonオブジェクトの作成に使用されることになっている別のファミリです。
以前は、これらのさまざまなファミリはすべて、プラットフォームの
malloc()
およびfree()
機能に限定されていました。 つまり、問題が発生してPyMem()
関数でメモリが割り当てられても問題はありませんでしたが、 PyObject()関数で解放されました。 2.5のobmallocへの変更により、これらのファミリは異なる処理を実行するようになり、不一致によりセグメンテーション違反が発生する可能性があります。 Python2.5を使用してC拡張モジュールを注意深くテストする必要があります。組み込みのセットタイプに公式のCAPIが追加されました。 PySet_New()および PyFrozenSet_New()を呼び出して新しいセットを作成し、 PySet_Add()および PySet_Discard()を呼び出して要素を追加および削除します、および PySet_Contains()および PySet_Size()を使用して、セットの状態を調べます。 (Raymond Hettingerによる寄稿。)
Cコードは、 Py_GetBuildInfo()関数を呼び出して、Pythonインタープリターの正確なリビジョンに関する情報を取得できるようになりました。この関数は、
"trunk:45355:45356M, Apr 13 2006, 07:42:19"
のようなビルド情報の文字列を返します。 (Barry Warsawによる寄稿。)2つの新しいマクロを使用して、現在のファイルに対してローカルなC関数を示すことができるため、より高速な呼び出し規約を使用できます。
Py_LOCAL(type)
は、指定された type の値を返すものとして関数を宣言し、高速呼び出し修飾子を使用します。Py_LOCAL_INLINE(type)
も同じことを行い、関数をインライン化するように要求します。python.h
が含まれる前にPY_LOCAL_AGGRESSIVE()
が定義されている場合、モジュールに対してより積極的な最適化のセットが有効になります。 結果をベンチマークして、これらの最適化によって実際にコードが高速化されるかどうかを確認する必要があります。 (NeedForSpeedスプリントでFredrik Lundhによって寄稿されました。)PyErr_NewException(name, base, dict)
は、 base 引数として基本クラスのタプルを受け入れることができるようになりました。 (Georg Brandlによる寄稿)警告を発行するための
PyErr_Warn()
関数は非推奨になり、この関数と呼び出し元を分離するスタックフレームの数を指定できるPyErr_WarnEx(category, message, stacklevel)
が採用されました。 1の stacklevel は、 PyErr_WarnEx()を呼び出す関数、2はその上の関数などです。 (Neal Norwitzによって追加されました。)CPythonインタープリターは引き続きCで記述されていますが、コードをC ++コンパイラーでエラーなしでコンパイルできるようになりました。 (Anthony Baxter、MartinvonLöwis、Skip Montanaroによって実装されました。)
PyRange_New()
機能が削除されました。 文書化されておらず、コアコードで使用されておらず、危険なほど緩いエラーチェックが行われていました。 万が一、拡張機能がそれを使用していた場合は、次のようなものに置き換えることができます。range = PyObject_CallFunction((PyObject*) &PyRange_Type, "lll", start, stop, step);
ポート固有の変更
- MacOS X(10.3以降):モジュールの動的ロードで、MacOS固有の関数ではなく
dlopen()
関数が使用されるようになりました。 - MacOS X:
--enable-universalsdk
スイッチが configure スクリプトに追加され、PowerPCプロセッサとIntelプロセッサの両方で実行できるユニバーサルバイナリとしてインタプリタをコンパイルします。 (RonaldOussorenによる寄稿; :issue: `2573` 。) - Windows:
.dll
は、拡張モジュールのファイル名拡張子としてサポートされなくなりました。.pyd
は、検索される唯一のファイル名拡張子になりました。
Python2.5への移植
このセクションでは、コードの変更が必要になる可能性のある前述の変更を一覧表示します。
- 現在、ASCIIはモジュールのデフォルトのエンコーディングです。 モジュールに8ビット文字の文字列リテラルが含まれているが、エンコーディング宣言がない場合は、構文エラーになります。 Python 2.4では、これにより構文エラーではなく警告がトリガーされました。
- 以前は、ジェネレータの
gi_frame
属性は常にフレームオブジェクトでした。 セクション PEP 342:新しいジェネレーター機能で説明されている PEP 342 の変更により、gi_frame
を [ X154X]。 - Unicode文字列とデフォルトのASCIIエンコーディングを使用してUnicodeに変換できない8ビット文字列を比較しようとすると、新しい警告 UnicodeWarning がトリガーされます。 以前は、このような比較では[X42X] UnicodeDecodeError 例外が発生していました。
- ライブラリ: csv モジュールは、複数行の引用符で囲まれたフィールドについてより厳密になりました。 ファイルにフィールド内に埋め込まれた改行が含まれている場合、入力は改行文字を保持する方法で行に分割する必要があります。
- ライブラリ: locale モジュールの format()関数は、%c har指定子が1つしか出現しない限り、以前は任意の文字列を受け入れていました。 Python 2.5では、引数は、周囲のテキストを含まない1つの%c har指定子である必要があります。
- ライブラリ: pickle および
cPickle
モジュールは、__reduce__()
メソッドからのNone
の戻り値を受け入れなくなりました。 メソッドは、代わりに引数のタプルを返す必要があります。 モジュールは、非推奨の bin キーワードパラメータも受け入れなくなりました。 - ライブラリ:
SimpleXMLRPCServer
クラスとDocXMLRPCServer
クラスに、XML-RPC操作を制限されたURLパスのセットに制限するrpc_paths
属性が追加されました。 デフォルトでは、'/'
と'/RPC2'
のみが許可されます。rpc_paths
をNone
に設定するか、タプルを空にすると、このパスチェックが無効になります。 - C API:多くの関数が int の代わりに
Py_ssize_t
を使用して、64ビットマシンでより多くのデータを処理できるようになりました。 警告を回避し、64ビットマシンをサポートするために、拡張コードで同じ変更を加える必要がある場合があります。 この変更の説明については、前のセクション PEP 353:インデックスタイプとしてのssize_tの使用を参照してください。 - C API:obmallocの変更は、 PyMem _ * と PyObject _ * ファミリーの関数の使用法を混在させないように注意する必要があることを意味します。 1つのファミリの * _ Malloc で割り当てられたメモリは、対応するファミリの * _ Free 関数で解放する必要があります。
謝辞
著者は、この記事のさまざまなドラフトについて提案、修正、および支援を提供してくれた次の人々に感謝します:Georg Brandl、Nick Coghlan、PhillipJ。 Eby、LarsGustäbel、Raymond Hettinger、RalfW。 Grosse-Kunstleve、Kent Johnson、Iain Lowe、MartinvonLöwis、Fredrik Lundh、Andrew McNamara、Skip Montanaro、Gustavo Niemeyer、Paul Prescod、James Pryor、Mike Rovner、Scott Weikart、Barry Warsaw、Thomas Wouters