2016-07-04 7 views
3

メタクラスhereについて読みながら、この区別はメタクラスに特有のものであり、私はそれがないと思われる場合、私は知らないが、私は、次のコードに出くわした:super().__init__()呼び出しは最初のを省略することを__new__と__init__は、スーパークラスにパントするときに、動作が異なるように見えるのはなぜですか?

class MetaBase(type): 
    def __new__(mcl, name, bases, nmspc): 
     print('MetaBase.__new__\n') 
     return super(MetaBase, mcl).__new__(mcl, name, bases, nmspc) 

    def __init__(cls, name, bases, nmspc): 
     print('MetaBase.__init__\n') 
     super(MetaBase, cls).__init__(name, bases, nmspc) 

は注意引数。私はそれがsuper()によって返されるどんなクラスのメソッドを呼び出しているとして、それは、暗黙のうちに渡された推測しています。彼らは通常、メタクラスの通常のクラスではなく、CLS/MCLにselfを伴うが、それは、私は通常、このような呼び出しが構築さ見てきた方法です。

super().__new__()コールでは、明示的にはmclが渡されます。なぜか分からない。署名は私と同じように見えます。

私は混乱しています。 super()は、それぞれ異なる場合がありますか?ここで何が起きているのですか?また、他の魔法を無効にするときにこれに噛まれることが予想されるでしょうか?

[編集:誰かが、異なる機能を説明しているthis questionの複製であると提案しました。同じ差があっ例のいくつかに展示されている間、それが存在するか、それが__new__に固有のかどうか、なぜ、私が述べて何も見えません。]

+4

'__new__'は静的メソッドです。 '__init__'はインスタンスメソッドです。 – spectras

+4

[Pythonの\\ \ new \ _ \ _と\ _ \ _ init \ _ \ _?]の可能な複製(http://stackoverflow.com/questions/674304/pythons-use-of-new-and- init) – spectras

+0

「__new__'の公式文書の最初の文章について:「[__new __()は静的メソッドです(特別なケースで宣言する必要はありません)](https://docs.python.org/3/reference/datamodel。html#object .__ new__) " – spectras

答えて

1

スーパー().__新しい__()の呼び出しは、しかし、明示的にMCLを渡します。私はなぜ 理解していない。署名は私と同じように見えます。

__new__の方法は、静的メソッドであるという点で異例ですが、特別なケースであり、そのように宣言する必要はありません。 staticメソッドは、必要な変数(この場合はメタクラス)を明示的に渡す必要があることを意味します。

対照的に、__init__は他の通常の方法と同様です。インスタンスからそれを探すと、インスタンスは自動的に最初の引数として渡されます。これは、cls.__init__(name, bases, nmspc)で直接親に電話をかけるか、またはsuper()super(MetaBase, cls).__init__(name, bases, nmspc)を使用して親を直接呼び出すかどうかに関係なく機能します。どちらも最初の引数としてclsに渡されます。これは、通常のクラスやメタクラスでバインドされたメソッドがどのように機能するかを示します。 スーパー()が使用されているかどうかは問題ではありません。

したがって、1つの奇妙なケースは、staticmethodであるため、__new__です。これは、定義によって自動的に前の動作がないためです。

他の魔法 の方法を無効にすると、これで噛まれることが予想されますか?

静的メソッドは多少まれです。そして、魔法の中では、__new__は私が考えることができる唯一のものです。だから、あなたは安全でなければなりません:-)

関連する問題