Python 2.2の新機能—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.8/whatsnew/2.2
移動先:案内検索

Python2.2の新機能

著者
午前 Kuchling

序章

この記事では、2002年10月14日にリリースされたPython2.2.2の新機能について説明します。 Python 2.2.2は、2001年12月21日に最初にリリースされたPython2.2のバグ修正リリースです。

Python 2.2は、「クリーンアップリリース」と考えることができます。 ジェネレーターやイテレーターなど、まったく新しい機能がいくつかありますが、ほとんどの変更は、重要で広範囲にわたるものですが、言語設計の不規則性や暗い部分をクリーンアップすることを目的としています。

この記事では、新機能の完全な仕様を提供するのではなく、便利な概要を提供します。 詳細については、 PythonライブラリリファレンスPythonリファレンスマニュアルなどのPython2.2のドキュメントを参照してください。 変更の完全な実装と設計の根拠を理解したい場合は、特定の新機能についてPEPを参照してください。


PEP 252および253:タイプとクラスの変更

Python 2.2での最大かつ最も広範囲にわたる変更は、Pythonのオブジェクトとクラスのモデルに対するものです。 変更には下位互換性があるはずなので、コードは変更されずに実行され続ける可能性がありますが、変更によりいくつかの驚くべき新機能が提供されます。 これを始める前に、この記事の最も長くて最も複雑なセクションで、変更の概要といくつかのコメントを提供します。

ずっと前に、Pythonの設計の欠陥をリストしたWebページを書きました。 最も重大な欠陥の1つは、Cで実装されたPython型をサブクラス化できないことでした。 特に、組み込み型をサブクラス化することはできないため、リストに1つの便利なメソッドを追加するために、リストなどをサブクラス化することはできません。 UserListモジュールは、リストのすべてのメソッドをサポートし、さらにサブクラス化できるクラスを提供しますが、通常のPythonリストを期待し、UserListを受け入れないCコードがたくさんあります。実例。

Python 2.2はこれを修正し、その過程でいくつかのエキサイティングな新機能を追加します。 簡単な要約:

  • リストや整数などの組み込み型をサブクラス化できます。サブクラスは、元の型を必要とするすべての場所で機能する必要があります。
  • 以前のバージョンのPythonで使用可能なインスタンスメソッドに加えて、静的メソッドとクラスメソッドを定義できるようになりました。
  • properties と呼ばれる新しいメカニズムを使用して、インスタンス属性にアクセスまたは設定するときにメソッドを自動的に呼び出すこともできます。 __getattr__()の多くの使用法は、代わりにプロパティを使用するように書き直すことができ、結果のコードをより単純かつ高速にします。 小さな副次的な利点として、属性にdocstringを含めることもできるようになりました。
  • インスタンスの有効な属性のリストは、 slot を使用して特定のセットに制限できるため、タイプミスから保護し、Pythonの将来のバージョンでより多くの最適化を可能にすることができます。

一部のユーザーは、これらすべての変更について懸念を表明しています。 確かに、彼らによれば、新機能はきちんとしていて、以前のバージョンのPythonでは不可能だったあらゆる種類のトリックに役立ちますが、言語をより複雑にします。 一部の人々は、Pythonのシンプルさを常に推奨しており、そのシンプルさが失われつつあると感じていると述べています。

個人的には心配する必要はないと思います。 新機能の多くは非常に難解であり、それらを意識する必要なしに多くのPythonコードを書くことができます。 簡単なクラスを書くことはこれまで以上に難しくないので、実際に必要でない限り、わざわざ学習したり教えたりする必要はありません。 以前はCからしか不可能だったいくつかの非常に複雑なタスクが、純粋なPythonで可能になります。私の考えでは、それはすべて良いことです。

新しい機能を機能させるために必要なすべてのコーナーケースと小さな変更をカバーしようとはしません。 代わりに、このセクションでは幅広いストロークのみをペイントします。 Python 2.2の新しいオブジェクトモデルの詳細については、関連リンクの「関連リンク」を参照してください。

新旧のクラス

まず、Python 2.2には、実際には2種類のクラスがあることを知っておく必要があります。クラシックまたは古いスタイルのクラスと新しいスタイルのクラスです。 古いスタイルのクラスモデルは、以前のバージョンのPythonのクラスモデルとまったく同じです。 このセクションで説明するすべての新機能は、新しいスタイルのクラスにのみ適用されます。 この相違は永遠に続くことを意図したものではありません。 最終的には、おそらくPython 3.0で、古いスタイルのクラスが削除されます。

では、新しいスタイルのクラスをどのように定義しますか? これを行うには、既存の新しいスタイルのクラスをサブクラス化します。 整数、リスト、辞書、さらにはファイルなど、Pythonの組み込み型のほとんどは、新しいスタイルのクラスになりました。 すべての組み込み型の基本クラスである object という名前の新しいスタイルのクラスも追加されたため、適切な組み込み型がない場合は、 object をサブクラス化できます。

class C(object):
    def __init__ (self):
        ...
    ...

つまり、基本クラスを持たない class ステートメントは、Python2.2では常にクラシッククラスです。 (実際には、__metaclass__という名前のモジュールレベルの変数を設定してこれを変更することもできます—詳細については PEP 253 を参照してください—ただし、をサブクラス化する方が簡単です。オブジェクト。)

組み込み型の型オブジェクトは、巧妙なトリックを使用して名前が付けられた組み込み型として使用できます。 Pythonには、常に int()float()、および str()という名前の組み込み関数があります。 2.2では、これらは機能しなくなりましたが、呼び出されたときにファクトリとして動作する型オブジェクトです。

>>> int
<type 'int'>
>>> int('123')
123

型のセットを完成させるために、 dict()file()などの新しい型オブジェクトが追加されました。 lock()メソッドをファイルオブジェクトに追加する、より興味深い例を次に示します。

class LockableFile(file):
    def lock (self, operation, length=0, start=0, whence=0):
        import fcntl
        return fcntl.lockf(self.fileno(), operation,
                           length, start, whence)

現在廃止されているposixfileモジュールには、ファイルオブジェクトのすべてのメソッドをエミュレートするクラスが含まれ、lock()メソッドも追加されましたが、このクラスは、ビルドされたものを期待する内部関数に渡すことができませんでした。ファイルでは、新しいLockableFileで可能なことです。


記述子

以前のバージョンのPythonでは、オブジェクトによってサポートされている属性とメソッドを検出する一貫した方法はありませんでした。 名前のリストである__members__および__methods__属性の定義など、いくつかの非公式の規則がありましたが、多くの場合、拡張タイプまたはクラスの作成者はそれらをわざわざ定義しませんでした。 オブジェクトの __ dict __ の検査にフォールバックすることもできますが、クラス継承または任意の__getattr__()フックが使用されている場合、これは依然として不正確である可能性があります。

新しいクラスモデルの根底にある大きなアイデアの1つは、記述子を使用してオブジェクトの属性を記述するためのAPIが形式化されていることです。 記述子は、属性の値を指定し、それがメソッドであるかフィールドであるかを示します。 記述子APIを使用すると、静的メソッドとクラスメソッド、およびよりエキゾチックな構造が可能になります。

属性記述子は、クラスオブジェクト内に存在するオブジェクトであり、独自の属性がいくつかあります。

  • __ name __ は属性の名前です。
  • __doc__は属性のdocstringです。
  • __get__(object)は、オブジェクトから属性値を取得するメソッドです。
  • __set__(object, value)は、オブジェクトの属性をに設定します。
  • __delete__(object, value)は、オブジェクト属性を削除します。

たとえば、obj.xと書く場合、Pythonが実際に実行する手順は次のとおりです。

descriptor = obj.__class__.x
descriptor.__get__(obj)

メソッドの場合、descriptor.__get__()は呼び出し可能な一時オブジェクトを返し、インスタンスとそのインスタンスで呼び出されるメソッドをラップします。 これが、静的メソッドとクラスメソッドが可能になった理由でもあります。 それらには、メソッドのみ、またはメソッドとクラスをラップする記述子があります。 これらの新しい種類のメソッドの簡単な説明として、静的メソッドはインスタンスに渡されないため、通常の関数に似ています。 クラスメソッドにはオブジェクトのクラスが渡されますが、オブジェクト自体には渡されません。 静的メソッドとクラスメソッドは次のように定義されます。

class C(object):
    def f(arg1, arg2):
        ...
    f = staticmethod(f)

    def g(cls, arg1, arg2):
        ...
    g = classmethod(g)

staticmethod()関数は、関数f()を受け取り、クラスオブジェクトに格納できるように、記述子にラップされて返します。 このようなメソッドを作成するための特別な構文(def static fdefstatic f()など)があると思われるかもしれませんが、そのような構文はまだ定義されていません。 これは、Pythonの将来のバージョンのために残されています。

スロットやプロパティなどのより多くの新機能も新しい種類の記述子として実装されており、何か新しいことを行う記述子クラスを作成することは難しくありません。 たとえば、メソッドのEiffelスタイルの前提条件と事後条件を記述できるようにする記述子クラスを記述できます。 この機能を使用したクラスは、次のように定義できます。

from eiffel import eiffelmethod

class C(object):
    def f(self, arg1, arg2):
        # The actual function
        ...
    def pre_f(self):
        # Check preconditions
        ...
    def post_f(self):
        # Check postconditions
        ...

    f = eiffelmethod(f, pre_f, post_f)

新しいeiffelmethod()を使用する人は、記述子について何も理解する必要がないことに注意してください。 これが、新機能が言語の基本的な複雑さを増やさないと私が思う理由です。 eiffelmethod()やZODBなどを作成するために、それについて知る必要のあるウィザードがいくつかありますが、ほとんどのユーザーは、結果のライブラリの上にコードを記述し、実装の詳細を無視します。


多重継承:ダイヤモンドルール

名前が解決されるルールを変更することで、多重継承もより便利になりました。 このクラスのセットを検討してください(Guido vanRossumによる PEP 253 からの図):

      class A:
        ^ ^  def save(self): ...
       /   \
      /     \
     /       \
    /         \
class B     class C:
    ^         ^  def save(self): ...
     \       /
      \     /
       \   /
        \ /
      class D

クラシッククラスのルックアップルールは単純ですが、それほどスマートではありません。 基本クラスは、左から右に向かって深さ優先で検索されます。 D.save()を参照すると、クラスDBAの順に検索され、save()が検索されて返されます。 C.save()はまったく見つかりません。 Csave()メソッドがCに固有の内部状態を保存している場合、それを呼び出さないと、その状態は保存されないため、これは悪いことです。

新しいスタイルのクラスは、説明が少し複雑な別のアルゴリズムに従いますが、この状況では正しいことを行います。 (Python 2.3は、このアルゴリズムをほとんどの場合同じ結果を生成するアルゴリズムに変更しますが、非常に複雑な継承グラフに対してより有用な結果を生成することに注意してください。)

  1. 従来のルックアップルールに従ってすべての基本クラスを一覧表示し、繰り返しアクセスする場合はクラスを複数回含めます。 上記の例では、訪問したクラスのリストは[DBACA]です。
  2. 重複するクラスがないかリストをスキャンします。 見つかった場合は、 last をリストに残して、1つを除くすべてのオカレンスを削除します。 上記の例では、重複を削除すると、リストは[DBCA]になります。

このルールに従って、D.save()を参照すると、C.save()が返されます。これは、私たちが求めている動作です。 このルックアップルールは、CommonLispが従うルールと同じです。 新しい組み込み関数 super()は、Pythonのアルゴリズムを再実装することなく、クラスのスーパークラスに到達する方法を提供します。 最も一般的に使用される形式はsuper(class, obj)で、これはバインドされたスーパークラスオブジェクト(実際のクラスオブジェクトではない)を返します。 この形式は、スーパークラスのメソッドを呼び出すためのメソッドで使用されます。 たとえば、Dsave()メソッドは次のようになります。

class D (B,C):
    def save (self):
        # Call superclass .save()
        super(D, self).save()
        # Save D's private information here
        ...

super()は、super(class)またはsuper(class1, class2)として呼び出されたときに、バインドされていないスーパークラスオブジェクトを返すこともできますが、これはおそらく役に立たないでしょう。


属性アクセス

かなりの数の洗練されたPythonクラスが、__getattr__()を使用して属性アクセスのフックを定義しています。 最も一般的には、これは便宜上、obj.parentなどの属性アクセスをobj.get_parentなどのメソッド呼び出しに自動的にマッピングすることでコードを読みやすくするために行われます。 Python 2.2は、属性アクセスを制御するいくつかの新しい方法を追加します。

まず、__getattr__(attr_name)は引き続き新しいスタイルのクラスでサポートされており、何も変更されていません。 以前と同様に、obj.fooにアクセスしようとしたときに、インスタンスのディクショナリにfooという名前の属性が見つからない場合に呼び出されます。

新しいスタイルのクラスは、新しいメソッド__getattribute__(attr_name)もサポートします。 2つの方法の違いは、__getattribute__()常にが呼び出され、属性にアクセスするたびに呼び出されるのに対し、古い__getattr__()fooが呼び出されない場合にのみ呼び出されることです。インスタンスの辞書にあります。

ただし、Python 2.2でのプロパティのサポートは、多くの場合、属性参照をトラップするためのより簡単な方法です。 __getattr__()メソッドの記述は、再帰を回避するためにメソッド内で通常の属性アクセスを使用できず、代わりに __ dict __ の内容をいじる必要があるため複雑です。 __getattr__()メソッドは、__repr__()__coerce__()などの他のメソッドをチェックするときにPythonによって呼び出されることになるため、これを念頭に置いて作成する必要があります。 最後に、すべての属性アクセスで関数を呼び出すと、パフォーマンスが大幅に低下します。

property は、属性を取得、設定、または削除する3つの関数とdocstringをパッケージ化した新しい組み込み型です。 たとえば、計算されるだけでなく設定可能なsize属性を定義する場合は、次のように記述できます。

class C(object):
    def get_size (self):
        result = ... computation ...
        return result
    def set_size (self, size):
        ... compute something based on the size
        and set internal state appropriately ...

    # Define a property.  The 'delete this attribute'
    # method is defined as None, so the attribute
    # can't be deleted.
    size = property(get_size, set_size,
                    None,
                    "Storage size of this instance")

これは、size属性をチェックし、インスタンスの[ X210X] __ dict __ 。 sizeへのアクセスも、関数を呼び出す作業を実行する必要がある唯一のアクセスであるため、他の属性への参照は通常の速度で実行されます。

最後に、新しい __ slots __ クラス属性を使用して、オブジェクトで参照できる属性のリストを制約することができます。 Pythonオブジェクトは通常、非常に動的です。 obj.new_attr=1を実行するだけで、いつでもインスタンスに新しい属性を定義できます。 新しいスタイルのクラスでは、 __ slots __ という名前のクラス属性を定義して、正当な属性を特定の名前のセットに制限できます。 例はこれを明らかにします:

>>> class C(object):
...     __slots__ = ('template', 'name')
...
>>> obj = C()
>>> print obj.template
None
>>> obj.template = 'Test'
>>> print obj.template
Test
>>> obj.newattr = None
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'C' object has no attribute 'newattr'

__ slots __ にリストされていない属性に割り当てようとすると、 AttributeError が発生することに注意してください。


PEP 234:イテレータ

2.2へのもう1つの重要な追加は、CレベルとPythonレベルの両方での反復インターフェースです。 オブジェクトは、呼び出し元がループオーバーする方法を定義できます。

2.1までのPythonバージョンでは、for item in objを機能させる通常の方法は、次のような__getitem__()メソッドを定義することです。

def __getitem__(self, index):
    return <next item>

__getitem__()は、オブジェクトのインデックス作成操作を定義するためにより適切に使用されるため、obj[5]を記述して6番目の要素を取得できます。 for ループをサポートするためだけにこれを使用している場合は、少し誤解を招く可能性があります。 ループオーバーしたいファイルのようなオブジェクトを考えてみましょう。 index パラメータは本質的に無意味です。クラスはおそらく、 index が毎回1ずつ増加する一連の__getitem__()呼び出しが行われると想定しているためです。 言い換えると、__getitem__()メソッドが存在するからといって、file[5]を使用して6番目の要素にランダムにアクセスできるというわけではありません。

Python 2.2では、反復を個別に実装でき、__getitem__()メソッドは、実際にランダムアクセスをサポートするクラスに制限できます。 イテレータの基本的な考え方は単純です。 新しい組み込み関数iter(obj)またはiter(C, sentinel)は、イテレーターを取得するために使用されます。 iter(obj)はオブジェクト obj のイテレータを返し、iter(C, sentinel)は呼び出し可能なオブジェクト Csentinelを返すまで呼び出すイテレータを返しますイテレータが完了したことを通知します。

Pythonクラスは、__iter__()メソッドを定義できます。このメソッドは、オブジェクトの新しいイテレーターを作成して返す必要があります。 オブジェクトがそれ自体のイテレータである場合、このメソッドはselfを返すことができます。 特に、イテレータは通常、独自のイテレータになります。 Cで実装された拡張タイプは、イテレーターを返すために tp_iter 関数を実装でき、イテレーターとして動作する拡張タイプは tp_iternext 関数を定義できます。

それで、このすべての後、イテレータは実際に何をしますか? 必須のメソッド next()が1つあります。このメソッドは引数をとらず、次の値を返します。 返される値がなくなったときに next()を呼び出すと、 StopIteration 例外が発生します。

>>> L = [1,2,3]
>>> i = iter(L)
>>> print i
<iterator object at 0x8116870>
>>> i.next()
1
>>> i.next()
2
>>> i.next()
3
>>> i.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
StopIteration
>>>

2.2では、Pythonの for ステートメントはシーケンスを予期しなくなりました。 iter()がイテレーターを返すものを期待しています。 下位互換性と利便性のために、__iter__()または tp_iter スロットを実装しないシーケンスに対してイテレーターが自動的に構築されるため、for i in [1,2,3]は引き続き機能します。 Pythonインタープリターがシーケンスをループする場合は常に、イテレータープロトコルを使用するように変更されました。 これは、次のようなことができることを意味します。

>>> L = [1,2,3]
>>> i = iter(L)
>>> a,b,c = i
>>> a,b,c
(1, 2, 3)

Pythonの基本的なタイプのいくつかにイテレータのサポートが追加されました。 ディクショナリで iter()を呼び出すと、キーをループするイテレータが返されます。

>>> m = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
...      'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}
>>> for key in m: print key, m[key]
...
Mar 3
Feb 2
Aug 8
Sep 9
May 5
Jun 6
Jul 7
Jan 1
Apr 4
Nov 11
Dec 12
Oct 10

これはデフォルトの動作です。 キー、値、またはキーと値のペアを反復処理する場合は、iterkeys()itervalues()、またはiteritems()メソッドを明示的に呼び出して、適切な反復子を取得できます。 関連するマイナーな変更で、 in 演算子が辞書で機能するようになったため、key in dictdict.has_key(key)と同等になりました。

ファイルにはイテレータも用意されており、ファイルに行がなくなるまで readline()メソッドを呼び出します。 これは、次のようなコードを使用してファイルの各行を読み取ることができることを意味します。

for line in file:
    # do something for each line
    ...

イテレータでのみ先に進むことができることに注意してください。 前の要素を取得したり、イテレータをリセットしたり、そのコピーを作成したりする方法はありません。 イテレータオブジェクトはそのような追加機能を提供できますが、イテレータプロトコルは next()メソッドのみを必要とします。

も参照してください

PEP 234 -イテレータ
Ka-PingYeeとGvRによって書かれました。 Python Labsのクルー、主にGvRとTimPetersによって実装されました。


PEP 255:シンプルなジェネレーター

ジェネレーターは別の新機能であり、イテレーターの導入と相互作用します。

PythonまたはCで関数呼び出しがどのように機能するかについては間違いなくよく知っています。 関数を呼び出すと、ローカル変数が作成されるプライベート名前空間が取得されます。 関数が return ステートメントに達すると、ローカル変数が破棄され、結果の値が呼び出し元に返されます。 後で同じ関数を呼び出すと、新しいローカル変数のセットが取得されます。 しかし、関数の終了時にローカル変数が破棄されなかった場合はどうなるでしょうか。 後で中断したところから機能を再開できるとしたらどうでしょうか。 これはジェネレーターが提供するものです。 それらは再開可能な機能と考えることができます。

ジェネレーター関数の最も簡単な例を次に示します。

def generate_ints(N):
    for i in range(N):
        yield i

新しいキーワード yield がジェネレーターに導入されました。 yieldステートメントを含む関数はすべてジェネレーター関数です。 これは、結果として関数を特別にコンパイルするPythonのバイトコードコンパイラによって検出されます。 新しいキーワードが導入されたため、モジュールのソースコードの先頭近くにfrom __future__ import generatorsステートメントを含めることにより、ジェネレーターをモジュールで明示的に有効にする必要があります。 Python 2.3では、このステートメントは不要になります。

ジェネレーター関数を呼び出すと、単一の値は返されません。 代わりに、イテレータプロトコルをサポートするジェネレータオブジェクトを返します。 yield ステートメントを実行すると、ジェネレーターは return ステートメントと同様に、iの値を出力します。 yieldステートメントとreturnステートメントの大きな違いは、yieldに達すると、ジェネレーターの実行状態が一時停止され、ローカル変数が保持されることです。 ジェネレータのnext()メソッドの次の呼び出しで、関数はyieldステートメントの直後に実行を再開します。 (複雑な理由により、yieldステートメントは tryfinally ステートメントのtryブロック内では許可されていません。 [を読んでください。 yieldと例外の間の相互作用の完全な説明については、X151X] PEP 255 を参照してください。)

generate_ints()ジェネレーターの使用例は次のとおりです。

>>> gen = generate_ints(3)
>>> gen
<generator object at 0x8117f90>
>>> gen.next()
0
>>> gen.next()
1
>>> gen.next()
2
>>> gen.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 2, in generate_ints
StopIteration

同様に、for i in generate_ints(5)またはa,b,c = generate_ints(3)と書くこともできます。

ジェネレーター関数内では、 return ステートメントは値なしでのみ使用でき、値の行列の終了を通知します。 その後、ジェネレータはそれ以上の値を返すことができなくなります。 return 5などの値を持つreturnは、ジェネレーター関数内の構文エラーです。 ジェネレーターの結果の終了は、 StopIteration を手動で上げるか、実行フローを関数の下部から外すことによっても示すことができます。

独自のクラスを作成し、ジェネレーターのすべてのローカル変数をインスタンス変数として格納することで、ジェネレーターの効果を手動で実現できます。 たとえば、整数のリストを返すには、self.countを0に設定し、 next()メソッドでself.countをインクリメントして返します。 ただし、適度に複雑なジェネレーターの場合、対応するクラスを作成するのは非常に面倒です。 Lib/test/test_generators.pyには、さらに興味深い例がいくつか含まれています。 最も単純なものは、ジェネレーターを再帰的に使用して、ツリーの順序どおりの走査を実装します。

# A recursive generator that generates Tree leaves in in-order.
def inorder(t):
    if t:
        for x in inorder(t.left):
            yield x
        yield t.label
        for x in inorder(t.right):
            yield x

Lib/test/test_generators.pyの他の2つの例では、N-Queensの問題($ N $の女王を$ NxN $のチェス盤に配置して、女王が他の女王を脅かさないようにする)とKnight's Tour(騎士を$ NxN $チェス盤のすべての正方形で、どの正方形にも2回アクセスする必要はありません)。

ジェネレーターのアイデアは、他のプログラミング言語、特にジェネレーターのアイデアが中心となるIcon( https://www.cs.arizona.edu/icon/ )から来ています。 Iconでは、すべての式と関数呼び出しはジェネレーターのように動作します。 https://www.cs.arizona.edu/icon/docs/ipd266.htm の「アイコンプログラミング言語の概要」の1つの例は、これがどのように見えるかを示しています。

sentence := "Store it in the neighboring harbor"
if (i := find("or", sentence)) > 5 then write(i)

アイコンでは、find()関数は、部分文字列「or」が見つかったインデックスを返します:3、23、33。 if ステートメントでは、iに最初に値3が割り当てられますが、3は5未満であるため、比較は失敗し、Iconは2番目の値23で再試行します。 23は5より大きいため、比較は成功し、コードは値23を画面に出力します。

Pythonは、ジェネレーターを中心的な概念として採用するという点で、Iconほどまでは進んでいません。 ジェネレーターはコアPython言語の新しい部分と見なされますが、ジェネレーターの学習や使用は必須ではありません。 彼らがあなたが持っている問題を解決しないならば、それらを無視してください。 Iconと比較したPythonのインターフェースの新しい機能の1つは、ジェネレーターの状態が、他の関数に渡したり、データ構造に格納したりできる具体的なオブジェクト(イテレーター)として表されることです。

も参照してください

PEP 255 -シンプルなジェネレーター
Neil Schemenauer、Tim Peters、Magnus LieHetlandによって書かれました。 主にNeilSchemenauerとTimPetersによって実装され、PythonLabsのクルーから他の修正が加えられました。


PEP 237:長整数と整数の統合

最近のバージョンでは、ほとんどのマシンで32ビット値である通常の整数と任意のサイズの長整数の区別が煩わしくなりました。 たとえば、2**32バイトより大きいファイルをサポートするプラットフォームでは、ファイルオブジェクトのtell()メソッドは長整数を返す必要があります。 ただし、Pythonには、単純な整数を予期し、代わりに長整数を指定するとエラーが発生するさまざまなビットがありました。 たとえば、Python 1.5では、通常の整数のみをスライスインデックスとして使用でき、'abc'[1L:]TypeError 例外を発生させて「スライスインデックスはintである必要があります」というメッセージを表示します。

Python 2.2は、必要に応じて値を短整数から長整数にシフトします。 コンパイラが適切なタイプを選択するようになったため、長整数リテラルを示すために「L」サフィックスは不要になりました。 (「L」サフィックスの使用は、Pythonの将来の2.xバージョンでは推奨されず、Python 2.4で警告がトリガーされ、おそらくPython 3.0で削除されます。) OverflowError を発生させるために使用された多くの操作が結果として長整数を返します。 例えば:

>>> 1234567890123
1234567890123L
>>> 2 ** 64
18446744073709551616L

ほとんどの場合、整数と長整数は同じように扱われるようになります。 type()組み込み関数を使用してそれらを区別することはできますが、それが必要になることはめったにありません。

も参照してください

PEP 237 -長整数と整数の統合
モシェザッカとグイドヴァンロッサムによって書かれました。 主にグイドヴァンロッサムによって実装されました。


PEP 238:除算演算子の変更

Python 2.2で最も物議を醸した変更は、最初からPythonにあった古い設計上の欠陥を修正する取り組みの始まりを告げるものです。 現在、Pythonの除算演算子/は、2つの整数引数が提示されると、Cの除算演算子のように動作します。小数部分がある場合に切り捨てられる整数結果を返します。 たとえば、3/2は1.5ではなく1であり、(-1)/2は-0.5ではなく-1です。 つまり、除算の結果は2つのオペランドの型によって予期せず変化する可能性があり、Pythonは動的に型付けされるため、オペランドの可能な型を判別するのが難しい場合があります。

(論争は、これが本当に設計上の欠陥であるかどうか、そしてこれを修正するために既存のコードを壊す価値があるかどうかについてです。 それはpython-devで終わりのない議論を引き起こし、2001年7月に comp.lang.python への酸っぱい皮肉な投稿の嵐に突入しました。 ここではどちらの側についても議論せず、2.2で実装されているものの説明に固執します。 引数と反引数の要約については、 PEP 238 をお読みください。)

この変更はコードを壊す可能性があるため、徐々に導入されています。 Python 2.2は移行を開始しますが、切り替えはPython3.0まで完了しません。

まず、 PEP 238 からいくつかの用語を借ります。 「真の除算」は、ほとんどの非プログラマーが精通している除算です。3/ 2は1.5、1 / 4は0.25などです。 「床分割」は、整数オペランドが与えられたときにPythonの/演算子が現在実行していることです。 結果は、真の除算によって返される値の下限です。 「クラシック分割」は、/の現在の混合動作です。 オペランドが整数の場合はフロア除算の結果を返し、オペランドの1つが浮動小数点数の場合は真の除算の結果を返します。

2.2で導入された変更は次のとおりです。

  • 新しい演算子//は、フロア分割演算子です。 (はい、C ++のコメント記号のように見えます。)// 常には、オペランドのタイプに関係なくフロア分割を実行するため、1 // 2は0および[ X170X] も0.0です。

    //はPython2.2で常に利用可能です。 __future__ステートメントを使用して有効にする必要はありません。

  • モジュールにfrom __future__ import divisionを含めると、/演算子が変更され、真の除算の結果が返されるため、1/2は0.5になります。 __future__ステートメントがなくても、/は依然として古典的な分割を意味します。 /のデフォルトの意味は、Python3.0まで変更されません。

  • クラスは、__truediv__()および__floordiv__()と呼ばれるメソッドを定義して、2つの除算演算子をオーバーロードできます。 経営幹部レベルでは、 PyNumberMethods 構造体にもスロットがあるため、拡張タイプで2つの演算子を定義できます。

  • Python 2.2は、コードが変更された分割セマンティクスで機能するかどうかをテストするためのいくつかのコマンドライン引数をサポートしています。 -Q warnでpythonを実行すると、2つの整数に除算が適用されるたびに警告が発行されます。 これを使用して、変更の影響を受けるコードを見つけて修正できます。 デフォルトでは、Python2.2は警告なしに単純に古典的な除算を実行します。 この警告は、Python2.3ではデフォルトでオンになっています。

も参照してください

PEP 238 -除算演算子の変更
モシェザッカとグイドヴァンロッサムによって書かれました。 グイドヴァンロッサムによって実装されました。


Unicodeの変更

PythonのUnicodeサポートは、2.2で少し拡張されました。 Unicode文字列は通常、16ビットの符号なし整数としてUCS-2として格納されます。 Python 2.2は、configureスクリプトに--enable-unicode=ucs4を指定することにより、内部エンコーディングとしてUCS-4、32ビット符号なし整数を使用するようにコンパイルすることもできます。 (--disable-unicodeを指定して、Unicodeサポートを完全に無効にすることもできます。)

UCS-4(「ワイドPython」)を使用するように構築されている場合、インタープリターはU +000000からU + 110000までのUnicode文字をネイティブに処理できるため、unichr()関数の有効な値の範囲はそれに応じて拡張されます。 UCS-2(「ナローPython」)を使用するようにコンパイルされたインタープリターを使用すると、65535を超える値でも、unichr()ValueError 例外が発生します。 これはすべて、 PEP 261 の「「ワイド」Unicode文字のサポート」で説明されています。 詳細については、それを参照してください。

もう1つの変更は、説明が簡単です。 Unicode文字列は、導入以来、文字列をUTF-8やLatin-1などの選択されたエンコーディングに変換するencode()メソッドをサポートしてきました。 2.2では、対称decode([*encoding*])メソッドが8ビット文字列(Unicode文字列ではない)に追加されました。 decode()は、文字列が指定されたエンコーディングであると想定してデコードし、コーデックによって返されるものをすべて返します。

この新機能を使用して、Unicodeに直接関係のないタスク用のコーデックが追加されました。 たとえば、uu-encoding、MIMEのbase64エンコーディング、および zlib モジュールによる圧縮用のコーデックが追加されました。

>>> s = """Here is a lengthy piece of redundant, overly verbose,
... and repetitive text.
... """
>>> data = s.encode('zlib')
>>> data
'x\x9c\r\xc9\xc1\r\x80 \x10\x04\xc0?Ul...'
>>> data.decode('zlib')
'Here is a lengthy piece of redundant, overly verbose,\nand repetitive text.\n'
>>> print s.encode('uu')
begin 666 <data>
M2&5R92!I<R!A(&QE;F=T:'D@<&EE8V4@;V8@<F5D=6YD86YT+"!O=F5R;'D@
>=F5R8F]S92P*86YD(')E<&5T:71I=F4@=&5X="X*

end
>>> "sheesh".encode('rot-13')
'furrfu'

クラスインスタンスをUnicodeに変換するには、__str__()と同様に、__unicode__()メソッドをクラスで定義できます。

encode()decode()、および__unicode__()は、Marc-AndréLemburgによって実装されました。 内部でのUCS-4の使用をサポートするための変更は、FredrikLundhとMartinvonLöwisによって実装されました。

も参照してください

PEP 261 -「ワイド」Unicode文字のサポート
ポールプレスコッドによって書かれました。


PEP 227:ネストされたスコープ

Python 2.1では、静的にネストされたスコープがオプション機能として追加され、from __future__ import nested_scopesディレクティブで有効になりました。 2.2では、ネストされたスコープを特別に有効にする必要がなくなり、常に存在するようになりました。 このセクションの残りの部分は、私の「Python2.1の新機能」ドキュメントからネストされたスコープの説明のコピーです。 2.1がリリースされたときに読んだ場合は、このセクションの残りの部分をスキップできます。

Python 2.1で導入され、2.2で完了した最大の変更は、Pythonのスコープルールです。 Python 2.0では、変数名の検索に使用される名前空間は、ローカル、モジュールレベル、および組み込みの名前空間の最大3つです。 それは彼らの直感的な期待と一致しなかったので、これはしばしば人々を驚かせました。 たとえば、ネストされた再帰関数定義は機能しません。

def f():
    ...
    def g(value):
        ...
        return g(value-1) + 1
    ...

名前gのバインディングがローカル名前空間にもモジュールレベルの名前空間にもないため、関数g()は常に NameError 例外を発生させます。 これは実際にはそれほど問題ではありませんが(このような内部関数を再帰的に定義する頻度はどれくらいですか?)、これも lambda 式を使用して不器用になり、これは実際には問題でした。 lambdaを使用するコードでは、引数のデフォルト値としてローカル変数を渡すことで、コピーされているローカル変数を見つけることができます。

def find(self, name):
    "Return list of any entries equal to 'name'"
    L = filter(lambda x, name=name: x == name,
               self.list_attribute)
    return L

その結果、強力に機能するスタイルで記述されたPythonコードの可読性が大幅に低下します。

Python 2.2の最も重要な変更は、この問題を修正するために静的スコープが言語に追加されたことです。 最初の効果として、上記の例ではname=nameのデフォルト引数は不要になりました。 簡単に言えば、指定された変数名に関数内の値が割り当てられていない場合(割り当て、または defclass 、または import ステートメントによって)、変数への参照は、囲んでいるスコープのローカル名前空間で検索されます。 ルールのより詳細な説明と実装の詳細は、PEPにあります。

この変更により、モジュールレベルと、さらに関数定義を含む関数内のローカル変数の両方で同じ変数名が使用されているコードで、互換性の問題が発生する可能性があります。 そもそもそのようなコードを読むのはかなり混乱していたので、これはかなりありそうもないようです。

この変更の副作用の1つは、from module import *およびexecステートメントが特定の条件下で関数スコープ内で不正にされることです。 Pythonリファレンスマニュアルには、from module import *はモジュールのトップレベルでのみ有効であるとずっと書かれていますが、CPythonインタープリターはこれまでこれを強制したことはありません。 ネストされたスコープの実装の一部として、Pythonソースをバイトコードに変換するコンパイラは、含まれているスコープ内の変数にアクセスするために異なるコードを生成する必要があります。 from module import *およびexecは、コンパイル時に認識できない名前をローカル名前空間に追加するため、コンパイラーがこれを理解することを不可能にします。 したがって、関数に関数定義または自由変数を含む lambda 式が含まれている場合、コンパイラーは SyntaxError 例外を発生させることでこれにフラグを立てます。

上記の説明をもう少し明確にするために、次に例を示します。

x = 1
def f():
    # The next line is a syntax error
    exec 'x=2'
    def g():
        return x

execステートメントを含む4行目は構文エラーです。これは、execxという名前の新しいローカル変数を定義し、その値にg()がアクセスする必要があるためです。

execはほとんどのPythonコードで使用されることはめったにないため、これはそれほど制限にはなりません(使用されると、とにかく設計が不十分であることを示していることがよくあります)。

も参照してください

PEP 227 -静的にネストされたスコープ
Jeremy Hyltonによって書かれ、実装されました。


新規および改善されたモジュール

  • xmlrpclibモジュールは、Fredrik Lundhによって標準ライブラリに提供され、XML-RPCクライアントの作成をサポートしています。 XML-RPCは、HTTPとXMLの上に構築された単純なリモートプロシージャコールプロトコルです。 たとえば、次のスニペットは、O'Reilly NetworkからRSSチャネルのリストを取得し、1つのチャネルの最近のヘッドラインをリストします。

    import xmlrpclib
    s = xmlrpclib.Server(
          'http://www.oreillynet.com/meerkat/xml-rpc/server.php')
    channels = s.meerkat.getChannels()
    # channels is a list of dictionaries, like this:
    # [{'id': 4, 'title': 'Freshmeat Daily News'}
    #  {'id': 190, 'title': '32Bits Online'},
    #  {'id': 4549, 'title': '3DGamers'}, ... ]
    
    # Get the items for one channel
    items = s.meerkat.getItems( {'channel': 4} )
    
    # 'items' is another list of dictionaries, like this:
    # [{'link': 'http://freshmeat.net/releases/52719/',
    #   'description': 'A utility which converts HTML to XSL FO.',
    #   'title': 'html2fo 0.3 (Default)'}, ... ]

    SimpleXMLRPCServerモジュールを使用すると、簡単なXML-RPCサーバーを簡単に作成できます。 XML-RPCの詳細については、 http://xmlrpc.scripting.com/を参照してください。

  • 新しい hmac モジュールは、 RFC 2104 で記述されたHMACアルゴリズムを実装します。 (GerhardHäringによる寄稿。)

  • 元々長いタプルを返していたいくつかの関数は、タプルのように動作するが、memberst_mtimeやtm_yearなどのニーモニック属性も持つ疑似シーケンスを返すようになりました。 拡張機能には、 os モジュールの stat()fstat()statvfs()fstatvfs()、およびlocaltime()gmtime()、およびstrptime()

    たとえば、古いタプルを使用してファイルのサイズを取得するには、file_size = os.stat(filename)[stat.ST_SIZE]のようなものを書くことになりますが、これはfile_size = os.stat(filename).st_sizeとしてより明確に書くことができます。

    この機能の元のパッチは、NickMathewsonによって提供されました。

  • Pythonプロファイラーは大幅に作り直され、出力のさまざまなエラーが修正されました。 (FredLによる寄稿。 ドレイクジュニア とティムピーターズ。)

  • socket モジュールは、IPv6をサポートするようにコンパイルできます。 Pythonのconfigureスクリプトに--enable-ipv6オプションを指定します。 (萩野純一郎「いとじゅん」寄稿)

  • C long long タイプをサポートするプラットフォームで、64ビット整数用の struct モジュールに2つの新しいフォーマット文字が追加されました。 qは符号付き64ビット整数用で、Qは符号なし整数用です。 値はPythonの長整数型で返されます。 (Tim Petersによる寄稿。)

  • インタプリタのインタラクティブモードには、Python2.1で導入された pydoc モジュールを使用してインタラクティブヘルプを提供する新しい組み込み関数 help()があります。 help(object)は、オブジェクトに関する利用可能なヘルプテキストを表示します。 引数のない help()を使用すると、オンラインヘルプユーティリティが表示され、関数、クラス、またはモジュールの名前を入力して、ヘルプテキストを読むことができます。 (Ka-PingYeeの pydoc モジュールを使用して、Guido van Rossumによって寄稿されました。)

  • re モジュールの基盤となるSREエンジンにさまざまなバグ修正とパフォーマンスの改善が行われました。 たとえば、 re.sub()および re.split()関数はCで書き直されました。 別の寄稿されたパッチは、特定のUnicode文字範囲を2倍高速化し、新しいfinditer()メソッドは、指定された文字列内の重複しないすべての一致に対してイテレーターを返します。 (SREはFredrikLundhによって管理されています。 BIGCHARSETパッチは、MartinvonLöwisによって提供されました。)

  • smtplib モジュールが RFC 2487 、「Secure SMTP over TLS」をサポートするようになったため、Pythonプログラムとメールトランスポート間のSMTPトラフィックを暗号化できるようになりました。エージェントにメッセージが渡されます。 smtplib はSMTP認証もサポートしています。 (GerhardHäringによる寄稿。)

  • PiersLauderによって維持されている imaplib モジュールは、 RFC 2342 、SORT、GETACL、およびSETACLで定義されているNAMESPACE拡張機能などのいくつかの新しい拡張機能をサポートしています。 (AnthonyBaxterとMichelPelletierによる寄稿。)

  • rfc822モジュールの電子メールアドレスの解析は、 RFC 2822 RFC 822 の更新に準拠するようになりました。 (モジュールの名前はではなくrfc2822に変更されます。)電子メールメッセージの解析と生成のための新しいパッケージ email も追加されました。 (Barry Warsawによって寄稿され、Mailmanでの彼の仕事から生まれました。)

  • difflib モジュールには、2つのテキスト行シーケンス間の変更の人間が読めるリスト(「デルタ」)を生成するための新しいDifferクラスが含まれるようになりました。 ndiff()restore()の2つのジェネレーター関数もあり、それぞれ2つのシーケンスからデルタを返すか、デルタから元のシーケンスの1つを返します。 (David Goodgerによって提供されたGrunt作業、その後生成を行ったTim Petersによるndiff.pyコードから。)

  • 新しい定数ascii_lettersascii_lowercase、およびascii_uppercasestring モジュールに追加されました。 標準ライブラリには、string.lettersを使用して範囲A-Za-zを意味するモジュールがいくつかありましたが、ロケールが使用されている場合、string.lettersはのセットによって異なるため、この仮定は正しくありません。現在のロケールで定義されている有効な文字。 バグのあるモジュールはすべて、代わりにascii_lettersを使用するように修正されました。 (未知の人によって報告されました;フレッドLによって修正されました。 ドレイクジュニア)

  • mimetypes モジュールでは、解析するファイル名のリストを取得するMimeTypesクラスを追加することで、代替のMIMEタイプデータベースを簡単に使用できるようになりました。 (FredLによる寄稿。 ドレイクジュニア)

  • Timerクラスが threading モジュールに追加され、将来のアクティビティのスケジューリングが可能になりました。 (Itamar Shtull-Trauringによる寄稿。)


インタプリタの変更と修正

一部の変更は、Python拡張モジュールを作成している、インタープリターを埋め込んでいる、またはインタープリター自体をハッキングしているため、経営幹部レベルでPythonインタープリターを扱う人々にのみ影響します。 Pythonコードのみを作成する場合、ここで説明する変更はどれも大きな影響はありません。

  • プロファイリングとトレースの関数をCで実装できるようになりました。これは、Pythonベースの関数よりもはるかに高速で動作でき、プロファイリングとトレースのオーバーヘッドを削減するはずです。 これは、Pythonの開発環境の作成者にとって興味深いものです。 2つの新しいC関数、 PyEval_SetProfile()PyEval_SetTrace()がPythonのAPIに追加されました。 既存の sys.setprofile()および sys.settrace()関数は引き続き存在し、新しいCレベルのインターフェイスを使用するように変更されただけです。 (FredLによる寄稿。 ドレイクジュニア)

  • 主にPythonデバッガーと開発ツールの実装者が関心を持つ別の低レベルAPIが追加されました。 PyInterpreterState_Head()および PyInterpreterState_Next()を使用すると、呼び出し元は既存のすべてのインタープリターオブジェクトをウォークスルーできます。 PyInterpreterState_ThreadHead()および PyThreadState_Next()を使用すると、特定のインタープリターのすべてのスレッド状態をループできます。 (David Beazleyによる寄稿。)

  • ガベージコレクターへのCレベルのインターフェイスが変更され、ガベージコレクションをサポートする拡張タイプを記述しやすくなり、関数の誤用をデバッグできるようになりました。 さまざまな関数のセマンティクスがわずかに異なるため、多数の関数の名前を変更する必要がありました。 古いAPIを使用する拡張機能は引き続きコンパイルされますが、ガベージコレクションには参加しません。したがって、2.2用に更新することはかなり優先度が高いと見なす必要があります。

    拡張モジュールを新しいAPIにアップグレードするには、次の手順を実行します。

  • Py_TPFLAGS_GC()の名前をPyTPFLAGS_HAVE_GC()に変更します。

  • PyObject_GC_New()または PyObject_GC_NewVar()を使用して割り当てます

    オブジェクト、および PyObject_GC_Del()を使用して、オブジェクトの割り当てを解除します。

  • PyObject_GC_Init()の名前を PyObject_GC_Track()に変更し、

    PyObject_GC_Fini()から PyObject_GC_UnTrack()

  • オブジェクトサイズの計算からPyGC_HEAD_SIZE()を削除します。

  • PyObject_AS_GC()およびPyObject_FROM_GC()への呼び出しを削除します。

  • 新しいetフォーマットシーケンスが PyArg_ParseTuple()に追加されました。 etは、パラメーターとエンコード名の両方を受け取り、パラメーターがUnicode文字列であることが判明した場合はパラメーターを指定されたエンコードに変換し、8ビット文字列の場合はパラメーターをそのままにします。目的のエンコーディングである必要があります。 これは、8ビット文字列がPythonのデフォルトのASCIIエンコーディングであると想定し、指定された新しいエンコーディングに変換するes形式の文字とは異なります。 (M.-Aによる寄稿 Lemburg、および次のセクションで説明するWindowsでのMBCSサポートに使用されます。)

  • 別の引数解析関数 PyArg_UnpackTuple()が追加されました。これは、より単純で、おそらくより高速です。 呼び出し元は、フォーマット文字列を指定する代わりに、予想される引数の最小数と最大数、および引数値が入力される PyObject * 変数へのポインターのセットを指定するだけです。

  • 2つの新しいフラグ METH_NOARGSMETH_O がメソッド定義テーブルで使用可能になり、引数のないメソッドまたは型指定されていない引数が1つあるメソッドの実装が簡素化されます。 このようなメソッドを呼び出すことは、 METH_VARARGS を使用する対応するメソッドを呼び出すよりも効率的です。 また、Cメソッドを記述する古いMETH_OLDARGSスタイルは正式に非推奨になりました。

  • 2つの新しいラッパー関数 PyOS_snprintf()PyOS_vsnprintf()が追加され、比較的新しいsnprintf()vsnprintf() Cのクロスプラットフォーム実装が提供されました。 libAPI。 標準のsprintf()およびvsprintf()関数とは対照的に、Pythonバージョンは、バッファオーバーランから保護するために使用されるバッファの境界をチェックします。 (M.-Aによる寄稿 レンブルグ。)

  • _PyTuple_Resize()関数は未使用のパラメーターを失ったため、3つではなく2つのパラメーターを受け取るようになりました。 3番目の引数は使用されておらず、以前のバージョンからPython2.2にコードを移植するときに単に破棄できます。


その他の変更と修正

いつものように、ソースツリー全体に散らばっている他の多くの改善とバグ修正がありました。 CVS変更ログを検索すると、Python 2.1と2.2の間で、527個のパッチが適用され、683個のバグが修正されていることがわかります。 2.2.1 139個のパッチを適用し、143個のバグを修正しました。 2.2.2 106個のパッチを適用し、82個のバグを修正しました。 これらの数値は過小評価される可能性があります。

より注目すべき変更点は次のとおりです。

  • Jack Jansenによって管理されているPython用のMacOSポートのコードは、メインのPython CVSツリーに保持されるようになり、MacOSXをサポートするために多くの変更が加えられました。

    最も重要な変更は、Pythonをフレームワークとして構築する機能です。これは、Pythonのコンパイル時にconfigureスクリプトに--enable-frameworkオプションを指定することで有効になります。 Jack Jansenによると、「これにより、自己完結型のPythonインストールとOSXフレームワークの「接着剤」が/Library/Frameworks/Python.framework(または別の場所)にインストールされます。 今のところ、これにすぐに追加される利点はほとんどありません(実際には、Pythonを見つけることができるようにPATHを変更する必要があるという欠点があります)が、MacPythonIDEを移植して本格的なPythonアプリケーションを作成するための基礎です、おそらくPythonを標準のOSAスクリプト言語として使用するなどです。」

    ウィンドウ処理、QuickTime、スクリプトなどのMacOSAPIにインターフェイスするほとんどのMacPythonツールボックスモジュール。 OS Xに移植されましたが、setup.pyではコメントアウトされています。 これらのモジュールを試してみたい人は、手動でコメントを外すことができます。

  • それらを受け取らない組み込み関数に渡されたキーワード引数により、 TypeError 例外が発生し、「 function はキーワード引数を取りません」というメッセージが表示されるようになりました。

  • Python 2.1で拡張モジュールとして追加された弱参照は、新しいスタイルのクラスの実装で使用されるため、コアの一部になりました。 そのため、 ReferenceError 例外は weakref モジュールから移動し、組み込みの例外になりました。

  • TimPetersによる新しいスクリプトTools/scripts/cleanfuture.pyは、Pythonソースコードから廃止された__future__ステートメントを自動的に削除します。

  • 追加の flags 引数が組み込み関数 compile()に追加されたため、__future__ステートメントの動作をシミュレートされたシェルで正しく観察できるようになりました。 IDLEおよび他の開発環境によって提示されたものとして。 これについては、 PEP 264 で説明されています。 (Michael Hudsonによる寄稿。)

  • Python 1.6で導入された新しいライセンスは、GPL互換ではありませんでした。 これは、2.2ライセンスに対するいくつかのマイナーなテキストの変更によって修正されたため、GPLされたプログラム内にPythonを再度埋め込むことが合法になりました。 Python自体はGPLされていませんが、代わりに、以前と同じように、BSDライセンスと本質的に同等のライセンスの下にあることに注意してください。 ライセンスの変更は、Python2.0.1および2.1.1リリースにも適用されました。

  • WindowsでUnicodeファイル名が表示されると、PythonはMicrosoftファイルAPIで使用されるように、MBCSでエンコードされた文字列に変換するようになりました。 MBCSはファイルAPIによって明示的に使用されるため、PythonがデフォルトのエンコーディングとしてASCIIを選択することは、煩わしいことがわかります。 Unixでは、locale.nl_langinfo(CODESET)が使用可能な場合、ロケールの文字セットが使用されます。 (Windowsのサポートは、Marc-AndréLemburgの支援を受けてMarkHammondによって提供されました。 UnixサポートはMartinvonLöwisによって追加されました。)

  • ラージファイルサポートがWindowsで有効になりました。 (Tim Petersによる寄稿。)

  • Tools/scripts/ftpmirror.pyスクリプトは、.netrcファイルがある場合はそれを解析するようになりました。 (Mike Rombergによる寄稿。)

  • xrange()関数によって返されるオブジェクトの一部の機能は非推奨になり、アクセスされると警告がトリガーされます。 Python2.3では表示されなくなります。 xrangeオブジェクトは、スライス、シーケンス乗算、および in 演算子をサポートすることにより、完全なシーケンスタイプのふりをしようとしましたが、これらの機能はほとんど使用されなかったため、バグがありました。 tolist()メソッドとstartstop、およびstep属性も非推奨になりました。 経営幹部レベルでは、PyRange_New()関数の4番目の引数repeatも非推奨になりました。

  • ディクショナリの実装には多数のパッチがありました。主に、ディクショナリにハッシュ値をこっそり変更したり、含まれているディクショナリを変更したオブジェクトが含まれている場合に、潜在的なコアダンプを修正するためです。 しばらくの間、python-devは、Michael Hudsonがコアダンプしたケースを見つけ、Tim Petersがバグを修正し、Michaelが別のケースを見つけ、それがぐるぐる回るという穏やかなリズムに陥りました。

  • Windowsでは、Stephen Hansenによって提供された多数のパッチのおかげで、PythonをBorland Cでコンパイルできるようになりましたが、結果はまだ完全には機能していません。 (しかし、このの進歩です…)

  • もう1つのWindowsの機能強化:Wise Solutionsは、PythonLabsにInstallerMaster8.1システムの使用を惜しみなく提供しました。 以前のPythonLabsWindowsインストーラーは、その時代を示し始めていたWise5.0aを使用していました。 (Tim Petersによってパッケージ化されました。)

  • .pywで終わるファイルをWindowsにインポートできるようになりました。 .pywはWindows専用のものであり、DOSコンソールがポップアップして出力を表示しないようにするために、PYTHON.EXEではなくPYTHONW.EXEを使用してスクリプトを実行する必要があることを示すために使用されます。 このパッチにより、モジュールとしても使用できる場合に備えて、このようなスクリプトをインポートできるようになります。 (David Bolenによって実装されました。)

  • PythonがC dlopen()関数を使用して拡張モジュールをロードするプラットフォームで、 sys.getdlopenflags()およびを使用してdlopen()が使用するフラグを設定できるようになりました。 ] sys.setdlopenflags()関数。 (Bram Stolkによる寄稿。)

  • pow()組み込み関数は、浮動小数点数が指定されている場合、3つの引数をサポートしなくなりました。 pow(x, y, z)(x**y) % zを返しますが、これは浮動小数点数には役立ちません。最終的な結果はプラットフォームによって予想外に異なります。 pow(2.0, 8.0, 7.0)などの呼び出しで、 TypeError 例外が発生するようになりました。


謝辞

著者は、この記事のさまざまなドラフトについて提案、修正、および支援を提供してくれた次の人々に感謝します:Fred Bremmer、Keith Briggs、Andrew Dalke、FredL。 Drake、Jr.、Carel Fellinger、David Goodger、Mark Hammond、Stephen Hansen、Michael Hudson、Jack Jansen、Marc-AndréLemburg、MartinvonLöwis、Fredrik Lundh、Michael McLay、Nick Mathewson、Paul Moore、Gustavo Niemeyer、Don O ' Donnell、Joonas Paalasma、Tim Peters、Jens Quade、Tom Reinhardt、Neil Schemenauer、Guido van Rossum、Greg Ward、Edward Welbourne