ホームページ > バックエンド開発 > Python チュートリアル > Pythonのマジックメソッド - カスタムシーケンスの詳細説明

Pythonのマジックメソッド - カスタムシーケンスの詳細説明

WBOY
リリース: 2016-08-04 08:55:41
オリジナル
1308 人が閲覧しました

カスタム シーケンスの関連するマジック メソッドにより、作成したクラスにシーケンスの特性を持たせることができ、Python の組み込みシーケンス (dict、タプル、リスト、文字列など) と同じように使用できるようになります。

この機能を実装したい場合は、Python の関連プロトコルに従う必要があります。いわゆる合意とは、何らかの合意された内容のことです。たとえば、クラスに反復を実装したい場合は、__iter__ と next (python3.x の __new__) という 2 つのマジック メソッドを実装する必要があります。 __iter__ はオブジェクトを返す必要があり、このオブジェクトは次のメソッドを実装する必要があり、通常は self 自体を返します。 next メソッドは呼び出されるたびに次の要素を返し、要素がなくなると StopIteration 例外をトリガーする必要があります。

実際、for ループの本質は、最初にオブジェクトの __iter__ メソッドを呼び出し、次に __iter__ メソッドによって返されるオブジェクトの次のメソッドを繰り返し呼び出し、StopIteration 例外がトリガーされたときに停止し、例外を内部で処理することです。したがって、例外がスローされたことはわかりません。

この関係はまさにインターフェイスのようなものです。これまでの記事のマジック メソッドを確認すると、多くの組み込み関数によって得られた結果が、対応するマジック メソッドの戻り値であることがわかります。

関連する魔法のメソッドは次のとおりです:

•__len__(自分)

•コンテナの長さを返します。変更可能コンテナと不変更コンテナの両方でこれを実装する必要があり、これはプロトコルの一部です。

•__getitem__(自分, キー)

•アイテムがアクセスされたときに self[key] を使用して生成される動作を定義します。これは、変更可能コンテナと不変更コンテナのプロトコルの一部でもあります。キーの型が間違っている場合は TypeError が発生し、キーに適切な値がない場合は KeyError が発生します。

•__setitem__(自身、キー、値)

•項目に値が割り当てられたときに、self[key] = value を使用して生成される動作を定義します。これは可変コンテナー プロトコルの一部でもあります。さらに、対応する状況では KeyError と TypeError も生成されます。

•__delitem__(自分、キー)

•アイテムが削除されたときに発生する動作を定義します。 (例: del self[key])。これは可変コンテナー プロトコルの一部です。無効なキーを使用する場合は、適切な例外をスローする必要があります。

•__iter__(自分)

•コンテナイテレータを返す 多くの場合、特に組み込みの iter() メソッドが呼び出された場合、および for x incontainer: メソッドがループに使用された場合に、イテレータが返されます。イテレータはそれ自体がオブジェクトであり、self を返す __iter__ メソッドを定義する必要があります。

•__逆__(自分)

•reversed()が呼ばれた時の動作を実装します。シーケンスの逆バージョンが返される必要があります。リストやタプルなど、シーケンスが順序付けされている場合にのみ実装します。

•__contains__(自分、アイテム)

•メンバーが存在するかどうかをテストするために呼び出したときと呼び出していないときに発生する動作を定義します。これはプロトコルでは必須ではありませんが、独自の要件に応じて実装できます。 __contains__ が定義されていない場合、Python はシーケンスを反復処理し、必要な値が見つかったときに True を返します。

•__missing__(自分、キー)

•dictのサブクラスで使用されます。辞書に存在しないキーにアクセスしたときに発生する動作を定義します。 (たとえば、辞書 d があり、「george」が辞書のキーではないときに d["george"] が使用された場合、 d.__missing__("george") が呼び出されます)。

これがコード例です:

リーリー

ここでは辞書をシミュレートするクラスを作成します。このクラスは内部で 2 つのリストを保持し、Key はキーを格納し、Value はインデックスを介して 1 対 1 に対応します。辞書をシミュレートします。

まず、__len__ メソッドを見てみましょう。プロトコルによれば、このメソッドはコンテナーの長さを返す必要があります。このクラスは 2 つのリストの長さが等しいことを要求するように設計されているため、理論上はその長さになります。ここでは、キーの長さを返すことを選択します。

次に、__getitem__ メソッドがあります。このメソッドは、a['scolia'] のときに a.__getitem__('scolia') を呼び出します。つまり、このメソッドは要素の取得を定義するもので、まずキー リストに組み込まれたインデックスを検索し、次にそのインデックスを使用して値リスト内の対応する要素を検索し、それを返すというものです。次に、さらに辞書として偽装するために、発生する可能性のある ValueError (項目がキー リストにない場合にトリガーされる例外) をキャッチし、辞書がキーを見つけられない場合に KeyError として偽装しました。

理論的には、上記の 2 つのメソッドが実装されている限り、不変のコンテナーを取得できます。でも物足りなさを感じたので拡張を続けました。

__setitem__(self, key, value)方法定义了 a['scolia'] = 'good' 这种操作时的行为,此时将会调用a.__setitem__('scolia', 'good') 因为是绑定方法,所以self是自动传递的,我们不用理。这里我也模拟了字典中对同一个键赋值时会造成覆盖的特性。这个方法不用返回任何值,所以return语句也省略了。

__delitem__(self, key)方法定义了del a['scolia'] 这类操作时候的行为,里面的‘scolia'就作为参数传进去。这里也进行了异常的转换。

只有实现里以上四个方法,就可以当做可变容器来使用了。有同学可能发现并没有切片对应的魔法方法,而事实上,我也暂时没有找到先,这部分内容先搁着一边。

接下来的 __str__ 是对应于 str() 函数,在类的表示中会继续讨论,这里是为了 print 语句好看才加进去的,因为print语句默认就是调用str()函数。

__iter__和next方法在开头的时候讨论过了,这里是为了能让其进行迭代操作而加入的。

__reversed__(self)方法返回一个倒序后的副本,这里体现了有序性,当然是否需要还是要看个人。

__contains__实现了成员判断,这里我们更关心value列表中的数据,所以判断的是value列表。该方法要求返回布尔值。

下面是相应的测试:

a = Foo('scolia', 'good')
a[123] = 321
a[456] = 654
a[789] = 987
print a
del a[789]
print a
for x, y in a:
  print x, y
print reversed(a)
print 123 in a
print 321 in a
ログイン後にコピー

•__missing__(self, key)

class Boo(dict):
  def __new__(cls, *args, **kwargs):
    return super(Boo, cls).__new__(cls)

  def __missing__(self, key):
    return 'The key(%s) can not be find.'% key
ログイン後にコピー

测试:

b = Boo()
b['scolia'] = 'good'
print b['scolia']
print b['123']
ログイン後にコピー

 

当然你也可以在找不到 key 的时候触发异常,具体实现看个人需求。

以上这篇python魔法方法-自定义序列详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート