问题
From all I understand about Python object oriented programming if a class has __call__
method defined that would be invoked if we use the instance of the class like a function call. For example:
class Employee:
def __init__(self,name,sal):
self.name = name
self.salary = sal
def __call__(self,value):
return self.salary * value
e = Employee("Subhayan",20000)
print (e(10))
So the __call__
method takes the object instance as the first argument.
I am just trying to understand metaclasses in Python and I read that type
is the default metaclass of all user defined classes.
If I define a basic custom metaclass in Python:
class Meta(type):
def __new__(meta, classname, supers, classdict):
# Run by inherited type.__call__
return type.__new__(meta, classname, supers, classdict)
Now as per the documentation given in the book the metaclass __new__
method would be run by the __call__
method inherited from type.
Now my question is to use the __call__
method of any class we have to have an object of that class and then call it as a function.
Here we don't have any object of type to use its __call__
function.
Can someone please explain to me how is the __call__
function of type class coming into picture?
回答1:
Any class is itself an instance of type "type" - therefore "calling" a class just calls the method __call__
on its class - which happens to be type's __call__
.
The effect of type.__call__
is exactly:
on code like:
class A:
pass
b = A()
type.__call__
receives the classA
itself as its first parameter.- It calls the
A.__new__
- in pseudocode we could writeinstace = A.__new__(cls)
as what runs. - That returns an instance of the "A" class
- Then it calls
__init__
on the instance(instance.__init__()
) - ...and returns that instance
return instance
However, if the the class itself is derived from "type" - i.e., it is the instantiation of a "new" class, extra steps are taken: The special value of the magic __class__
variable is filled in any of the class methods - if any of those methods use a call to super
. And on Python 3.6, these 2 further steps: any of the class attributes that define a __set_name__
method are called, and the class's __init_subclass__
method is called.
回答2:
Remember, type
is a metaclass so it's instances are classes, not objects. Than means (among other things) that when you do this:
e= Employee(*args,**kwargs)
You are calling Employee.__init__
and some methods from your metaclass including Meta.__call__
, the same way that when you do .
print (e(10))
you are invoking your custom __call__
method.
Take for example this Singleton
metaclass:
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class MyClass(BaseClass):
__metaclass__ = Singleton
Now every time you create a new instance of MyClass
, the __call__
method in the metaclass is called before the actual instance is created allowing you to check if a previous one exists and return that instead.
Hope this helps.
来源:https://stackoverflow.com/questions/44178162/call-method-of-type-class