2017-08-06 45 views
3

從我的理解類內部__call__方法瞭解__call__實現函數調用操作符,例如:使用元類

class Foo: 
    def __init__(self): 
     print("I'm inside the __init__ method") 

    def __call__(self): 
     print("I'm inside the __call__ method") 

x = Foo() #outputs "I'm inside the __init__ method" 
x() #outputs "I'm inside the __call__ method" 

不過,我經歷的Python Cookbook和作家定義的元類控制實例創建,以便您不能直接實例化對象。這是他如何做的:

class NoInstance(type): 
    def __call__(self, *args, **kwargs): 
     raise TypeError("Can't instantaite class directly") 


class Spam(metaclass=NoInstance): 
    @staticmethod 
    def grok(x): 
     print("Spam.grok") 

Spam.grok(42) #outputs "Spam.grok" 

s = Spam() #outputs TypeError: Can't instantaite class directly 

不過,我不明白的是s()是如何不叫,但它的__call__方法被調用。這個怎麼用?

回答

2

元類實現類將如何表現(而不是實例)。所以當你看創建實例時:

x = Foo() 

這個字面意思是「調用」類Foo。這就是爲什麼元類的__call__之前類的__new____init__方法初始化實例被調用。


由於@Take_Care_在評論上的元類一分大的ressource是ionelmc's blog post關於「理解的Python元類」中指出。在博客中的一個圖像直接適用於您的情況:

enter image description here

圖像直接從博客文章複製。

+1

偉大而簡單的答案! 。如果OP想要更多的東西:https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/ –

+1

謝謝。這正是我一直在尋找的! – electro7912

1

類只是其元類的實例。由於元類定義__call__(),調用元類的實例,即,類,作爲一個功能,即作爲構造,將調用它。