2

いくつかのコンテナ オブジェクトを実装します。

class A:
    def __init__(self, L):
        self.L = list(L)
    def __len__(self):
        return len(self.L)

class B:
    def __init__(self, L):
        self.L = list(L)
        self.__len__ = self.L.__len__

最初のケースでは、len().__len__()

>>> a = A(range(10))
>>> a.__len__()
10
>>> len(a)
10

しかし、2番目のケースでは、でエラーが発生しlen()ます。

>>> b = B(range(10))
>>> b.__len__()
10
>>> len(b)
Traceback (most recent call last):
  File "<pyshell#93>", line 1, in <module>
    len(b)
TypeError: object of type 'B' has no len()
  1. なぜlen()2 番目のケースでは機能しないのに、.__len__()定義されて正しく機能するのですか?
  2. 一般に、あるオブジェクトから別のオブジェクトにいくつかのメソッドを割り当てることは問題ありませんか? 私がしたようにself.L.__len__()
4

2 に答える 2

3

これを行うことはできません。 のような特別なフック メソッド__len__は、インスタンスではなく、常に型で検索されます。

つまり、ではなくlen(ob)を呼び出します。type(ob).__len__(ob) ob.__len__()

Special method lookup documentationを参照してください。これが以前の回答である理由を説明しました。

特別なフックではないメソッド(2 つのアンダースコアで開始および終了する) については、メソッドをインスタンスに自由に割り当てることができます。それを妨げる技術的な理由はありません。

あなたの目標がファサードオブジェクトを提供することである場合は、必ずメソッドをコピーしてください。それを行うことの明らかな欠点は見当たりません。ラッパー メソッドを介してルーティングする代わりに、インスタンスでメソッドを直接呼び出すと、パフォーマンスがわずかに向上します (ラッパー メソッドのスタック プッシュとポップを保存します)。

于 2013-03-01T14:18:53.160 に答える
2

優れた Python のドキュメントは、次のことを示しています。

新しいスタイルのクラスの場合、特別なメソッドの暗黙的な呼び出しは、オブジェクトのインスタンス ディクショナリではなく、オブジェクトの型で定義されている場合にのみ正しく機能することが保証されます。

于 2013-03-01T14:19:21.717 に答える