5

以下のように、スーパー メソッドを越えて親のメソッドを呼び出したときに、バインドされたメソッドの "self" 引数を無視できることを私は知っています。

class Foo(object):
    def __init__(self):
        super(Foo, self).__init__() # We needn't pass in the "self" argument
        # ...

しかし、何かが__new__方法で異なっていました:

class Bar(object):
    def __new__(cls, *args, **kwargs):
        return super(Bar, cls).__new__(cls, *args, **kwargs) # Why need a "cls" argument?
4

1 に答える 1

8

__new__インスタンスメソッドではありません。クラスオブジェクトに渡されるのは静的メソッドです(クラスメソッドでもありません)。

__new__ドキュメントから:

__new__()インスタンスが要求されたクラスを最初の引数として受け取る静的メソッド (特殊なケースであるため、そのように宣言する必要はありません) です。

そのため、MRO でsuper()次のメソッドを検索するために使用する場合でも、明示的に渡す必要があります。__new__cls

アンダースコアが 2 つある特別なメソッドは、通常はtypeで検索されるため、クラスのメタクラス (type()デフォルト) で検索されます。__new__クラス自体で直接宣言したため、それは機能しません。そのため、記述子プロトコルも適用できませ(これは、通常、関数をクラス メソッドとインスタンス メソッドのバインドされたメソッドに変換するものです)。したがって、__new__フックは特殊なケースにする必要があり、バインドされることはありません。

于 2013-11-14T08:51:39.303 に答える