Pythonは、1989年のクリスマスの週に、生みの親であるGuido van Rossum氏が退屈しのぎに開発したものでした。そして今では、YouTube、Reddit、Dropboxなど、インターネット上で最も人気のあるウェブサイトを動かし、世界中の何百万人もの開発者に利用されています。.
今日は、Python 3.7で見られる主な変更点や追加された機能を紹介します。まずは、重要なものから始めましょう。
レガシーC言語のロケールをUTF-8ベースのロケールに強制変換する
これまで、Windows以外のプラットフォームでデフォルトのCロケールが意味する「7ビットASCII」テキストエンコーディングの仮定を処理するための実行可能なデフォルト戦略を決定することは、継続的な課題となっていました。
Python 3.7 では、デフォルトのインタプリタのコマンドラインインタフェースがアップグレードされ、ロケールを UTF-8 ベースのロケールに自動的に変換するようになりました。自動設定の LC_CTYPE は、ロケール対応の C 拡張(readline など)とコアインタプリタの両方が、デフォルトのテキストエンコーディングとして ASCII ではなく UTF-8 を使用することを意味します。
stdoutおよびstdinのデフォルトのエラーハンドラは、strictではなくsurrogateescapeになりました。stderrでは、ロケールに関係なくbackslashreplaceです。
デフォルトでは、ロケール強制は無音です。しかし、ロケール統合に関連する問題のデバッグを支援するために、PYTHONCOERCECLOCALE=warn を調整することで、明示的な警告を要求することができます。また、コアインタプリタの初期化中にレガシーCロケールが有効なままであれば、Pythonランタイムは警告を返すようになります。
CPythonでスレッドローカルストレージを実現する新しいC言語のAPI
現在のTLS(スレッド・ローカル・ストレージ)APIでは、各プラットフォームのTLSキーをint型で表現しています。しかし、これはPOSIXに準拠しておらず、また移植性もありません。
新しいPythonのバージョンでは、CPythonインタープリタ内の現在のTLS APIをオーバーライドする新しいTSS (thread specific storage) APIをCPythonに提供することで、この問題を解決しました。
新しいAPIではint型ではなく、TSSキーを表現するために新しいPy_tss_t型を使用します。これにより、ネイティブのTLSキーがintに適切にキャストできない方法で定義されているプラットフォーム上でCPythonを開発することができるようになります。TLS APIのすべての関数はノーオペで、すぐに失敗を返します。
新内蔵関数 Breakpoint()
Python 3.7 には、呼び出しの時点で Python デバッガに入る新しい組み込み関数 breakpoint() があります。この関数は、sys.breakpointhook()を呼び出し、pdbをインポートし、pdb.set_trace()を呼び出します。sys.breakpointhook()を選択している関数にバインドすることで、breakpoint()はどんなデバッガにも入ることができます。
新しい環境変数PYTHONBREAKPOINT()により、外部プロセスがブレークポイントの扱いを制御できるようになりました。PYTHONBREAKPOINT=0を設定すると、デバッグが無効になり、sys.breakpointhook()は直ちにNoneを返します。
HTTPサーバ
HTTP If-Modified-SinceヘッダはSimpleHTTPRequestHandlerでサポートされています。ヘッダーで指定された時間が経過しても対象のファイルが変更されない場合、サーバーは304の応答ステータスを返します。
デフォルトでは、サーバは現在の作業ディレクトリを提供しますが、モジュールサーバのコマンドラインに-directoryを、SimpleHTTPRequestHandlerにパラメータdirectoryを追加することで、サーバに特定のディレクトリを使用させることができます。
改良型モジュール – argparse
parse_intermixed_args()とparse_known_intermixed_args()では、多くのUnixコマンドのように、オプション引数と位置引数を混在させることができます。
しかし,これらのパーサは,argparseのすべての機能をサポートしているわけではなく,サポートされていない機能が使われると例外が発生します.具体的には,argparse.REMAINDERや,positionalとoptionalの両方を含む相互に排他的なグループはサポートされていません.
カレンダーとCGI
HTMLCalendarクラスには新しい属性が追加され、生成されたHTMLカレンダーのCSSクラスを簡単にカスタマイズできるようになりました。
parse_multipart()は、FieldStorageと同じ出力を返します。ファイル以外のフィールドでは、バイトではなく文字列のリストが返されます。使いやすいのですが、メガバイト単位でのアップロードを想定している場合は効率的ではありません。その場合は、FieldStorageクラスの方が柔軟性があります。
ElementPathとZipapp
find()のElementPath述語は、[. = “text”]を介して、現在のノードのテキストを比較することができます。これは、完全なテキスト・コンテンツ(子孫を含む)が与えられたテキストに等しいすべての要素を選びます。さらに、述語は読みやすさのためにスペースを許容します。
zipapp.create_archive()関数は、アーカイブに含めるファイルを選択できる filter 引数(オプション)と、圧縮されたアーカイブを作成する compressed 引数(オプション)を取ります。
メソッド呼び出しと文字列検索の高速化
Python 3.7 は、メソッド呼び出しの際にバインドされたメソッドオブジェクトのインスタンス化を避けるためのCALL_METHOD と LOAD_METHOD という2つの新しいオペコードを搭載しています。これにより、前バージョンと比較して、メソッド呼び出しが最大20%高速になりました。
文字列中の奇妙な Unicode 文字 (例えば “Є”) の検索は、以前は他の通常の文字を検索するよりも約 25 倍低速でした。Python 3.7では、最悪のケースでも3倍の速度しか出ません。
また、正規表現の大文字・小文字を区別しない検索にも改良が加えられました。いくつかのパターンの検索が最大で20倍速くなりました。
C API
PyThread_get_thread_ident()とPyThread_start_new_thread()の結果タイプとPyThreadState_SetAsyncExc()のidパラメータがlongからunsigned longにアップグレードされました。
PyUnicode_AsWideCharString()は、wchar_t* stringがNULL文字を持ち、第2引数(size)がNULLの場合、ValueErrorを返します。
set_trace()のDisとヘッダ
dis()は、内包、入れ子になった関数、ジェネレータ式、入れ子になったクラスを開発するためのコードなど、入れ子になったコードオブジェクトをディスアセンブルするために使用できます。
また、set_trace()にヘッダーキーワードのみの引数(オプション)を含めることができるようになりました。デバッグが始まる直前にコンソールに出力されます。
その他の変更
bytearray.fromhex()および bytes.fromhex()が、スペースだけでなく ASCII のホワイトスペースも無視するようになりました。
255 個以上の引数を関数に渡すことができるようになりました。また、関数は 255 個以上のパラメータを持つことができます。
from … import … がクラッシュしたときに ImportError がモジュール名とファイルパスを表示するようになりました。
b2a_uu()はオプションの’backtick’キーワード引数を受け付けるようになりました。これが真の場合、ゼロはスペースではなく’`’で表されます。