了解元类的__call__ [英] Understanding __call__ with metaclasses

查看:168
本文介绍了了解元类的__call__的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,类中的 __ call __ 方法实现了函数调用运算符,例如:

  class Foo:
def __init __(self):
print(我在__init__方法中)

def __call __(self) :
print(我在__call__方法中)

x = Foo()#outputs我在__init__方法中
x()#outputs我在__call__方法中

但是,我正在通过



图像直接从博客文章中复制。


From my understanding the __call__ method inside a class implements the function call operator, for example:

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"

However, I'm going through the Python Cookbook and the writer defined a metaclass to control instance creation so that you can't instantiate an object directly. This is how he did it:

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

However, what I don't get is how s() wasn't called, yet it's __call__ method was called. How does this work?

解决方案

Metaclasses implement how the class will behave (not the instance). So when you look at the instance creation:

x = Foo()

This literally "calls" the class Foo. That's why __call__ of the metaclass is invoked before the __new__ and __init__ methods of your class initialize the instance.


As @Take_Care_ pointed out in the comments one great ressource on metaclasses is ionelmc's blog post about "Understanding Python metaclasses". One image in that blog post directly applies to your situation:

The image is directly copied from the blog post.

这篇关于了解元类的__call__的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆