のような特別なメソッド__contains__
は、インスタンスではなく、クラスで定義された場合にのみ特別です (ただし、Python 2 のレガシー クラスは例外であり、いずれにせよ使用すべきではありません)。
したがって、クラス レベルで委任を行います。
class A(object):
def __init__(self):
self.mydict = {}
def __contains__(self, other):
return self.mydict.__contains__(other)
私は実際には後者を と綴りたいと思ってreturn other in self.mydict
いますが、それは小さなスタイルの問題です.
編集:「特別なメソッドの完全に動的なインスタンスごとのリダイレクト」(提供される古いスタイルのクラスなど)が不可欠な場合、新しいスタイルのクラスでそれを実装することは難しくありません。そのような独特の必要性を持つ各インスタンスが必要なだけです独自の特別なクラスにラップされます。例えば:
class BlackMagic(object):
def __init__(self):
self.mydict = {}
self.__class__ = type(self.__class__.__name__, (self.__class__,), {})
self.__class__.__contains__ = self.mydict.__contains__
self.__class__
基本的に、新しいクラス オブジェクト (前のクラス オブジェクトと同じように動作しますが、空の dict があり、これ以外のインスタンスはありません) に再割り当てする黒魔術を少し行った後、self
古いスタイルのクラスのどこにでもself.__magicname__
割り当てます。代わりにself.__class__.__magicname__
(また、通常の Python 関数ではなく、組み込みの orstaticmethod
であることを確認してください。もちろん、別のケースで、インスタンスで呼び出されたときに を受け取りたい場合を除きself
ます)。
ちなみに、このクラスin
のインスタンスの演算子は、たまたま以前に提案されたソリューションのどれよりも高速です。継承と記述子を含むルートは、オーバーヘッドを少し削減します)。BlackMagic
-mtimeit
built-in method
インスタンスごとのアイデアを自動化するメタクラスをself.__class__
書くのは難しくありません (生成されたクラスのメソッドで汚い仕事をすることができ__new__
、インスタンスに割り当てられている場合は、すべてのマジック名をクラスに実際に割り当てるように設定することもできます。__setattr__
または多くの、多くのプロパティ)。しかし、それは、この機能の必要性が本当に広まった場合にのみ正当化されます (たとえば、「インスタンスごとの特別なメソッド」を自由に使用する巨大な古代の Python 1.5.2 プロジェクトを、Python 3 を含む最新の Python に移植する場合)。
「賢い」または「黒魔術」のソリューションをお勧めしますか? いいえ、そうではありません。ほとんどの場合、物事を単純明快な方法で行う方が優れています。しかし、ここでは「ほぼ」という言葉が重要であり、その使用が実際に正当化される可能性がある、まれではあるが存在しないわけではない状況のために、このような高度な「フック」を手元に用意しておくと便利です。