如果一个类定义了__call__
方法,如果我们像函数调用一样使用类的实例,那么我就会理解Python面向对象编程。例如:
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))
因此__call__
方法将对象实例作为第一个参数。
我只是想了解Python中的元类,我读到type
是所有用户定义类的默认元类。
如果我在Python中定义基本的自定义元类:
class Meta(type):
def __new__(meta, classname, supers, classdict):
# Run by inherited type.__call__
return type.__new__(meta, classname, supers, classdict)
现在根据本书中给出的文档,元类__new__
方法将由从类型继承的__call__
方法运行。
现在我的问题是使用我们拥有的任何类的__call__
方法来获得该类的对象,然后将其称为函数。
这里我们没有任何类型的对象来使用它的__call__
函数。
有人可以向我解释一下类型类的__call__
功能是如何形成的?
答案 0 :(得分:2)
任何类本身都是类型"类型"的实例。 - 因此"呼叫"一个类只调用其类中的方法__call__
- 恰好是类型__call__
。
type.__call__
的效果恰好如下:
代码如下:
class A:
pass
b = A()
type.__call__
收到类A
本身作为其第一个参数。 A.__new__
- 在伪代码中我们可以编写instace = A.__new__(cls)
作为运行。 __init__
)instance.__init__()
return instance
但是,如果类本身来自"类型" - 即,它是" new"的实例化。 class,采取额外步骤:在任何类方法中填充magic __class__
变量的特殊值 - 如果这些方法中的任何一个使用对super
的调用。在Python 3.6上,还有以下两个步骤:调用定义__set_name__
方法的任何类属性,并调用类的__init_subclass__
方法。
答案 1 :(得分:1)
请记住,type
是一个元类,因此它的实例是类,而不是对象。当你这样做时,意味着(除其他外):
e= Employee(*args,**kwargs)
您正在调用Employee.__init__
以及您的元类中的一些方法,包括Meta.__call__
,与您的方法相同。
print (e(10))
您正在调用自定义__call__
方法。
以此Singleton
元类:
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
现在,每次创建MyClass
的新实例时,元类中的__call__
方法都会被称为,之后创建实际实例,以便您检查以前是否存在一个存在并返回。
希望这有帮助。