Python 可以通过函数和常规类编写元类。 类对象是通过 type() 在函数和常规类之间创建的。
python 工厂函数定义了一个外部函数,该函数生成并返回嵌套函数,因此调用工厂函数将获得对嵌套函数的引用。 有关详细信息,请参阅 Python 嵌套函数范围
任何可调用对象都可以用作元类,例如函数,只要它接收传递的参数并返回与目标类兼容的对象即可。 因为可调用对象有一个调用(方法。 class 语句还调用 type() 方法,该方法触发 call() 方法。
用法:
定义元类。描述:定义一个工厂函数,该函数接受三个输入参数,将它们馈送到 type() 内置函数中,并返回由 type() 生成的可调用对象类对象。def metafunc(classname,supers,classdict):
passreturn type(classname,supers,classdict)
使用元类。
class classb(classa,metaclass=metafunc)
手动调用 type() 内置函数以创建类对象。 有关详细信息,请参阅 Python 元类模型和类语句协议
classname: 字符串,类名;
supers:元组,用于保存基类;
classdict: 类属性字典;
返回值:创建一个名为 classname 的类对象,类型化为 type。
根据 class 语句协议,metaclass,即 type() 在 class 语句的末尾自动调用。
例
>>def metafunc(classname,supers,classdict):用法:print('工厂函数 metafunctype:','classname: %s' % classname,'supers: %s' % supers,'classdict: %s' % classdict,sep='')
return type(classname,supers,classdict)
>class classa:pass
>class classb(classa,metaclass=metafunc):
name='梯形图读取线'
def meth(self,arg):
传递工厂函数 MetaFunctype:
classname: classb
supers:
classdict:
>cb=classb()
>cb.name
梯形图读取线'>>type(metafunc)
>type(classb)
>type(cb)
定义。描述:通过元类的元类重载 type's call( 方法,显式调用 type 的 call( 方法,以及触发器类型的子类的 new ( 和 init() 方法。class supermeta(type):
def __call__(meta,classname,supers,classdict):
passreturn type.__call__(meta,classname,supers,classdict)
class submeta(type,metaclass=supermeta):
def __new__(meta,classname,supers,classdict):
passreturn type.__new__(meta,classname,supers,classdict)
def __init__(class,classname,supers,classdict):
通行证使用。
class classb(classa,metaclass=submeta):pass
1)定义元类子元,继承类型,指定元类metaclass=supermeta;
2)定义元类的元类supermeta,继承类型,重载调用(method;
3)客户端类classb通过metaclass=submeta指定元类;
4)通过类协议触发元类子元,然后触发元类调用的元类超元(method;
5) Supermeta 的调用方法显式调用类型__call__(
6) type.调用 (调用子类 submeta 的 new ( 和 init (方法;
7) submeta 的 new ( 方法 submeta 显式调用 new ( class 对象,该对象被分配给客户端类 classb;
例
>>class supermeta(type):用法:def __call__(meta,classname,supers,classdict):
print('调用 supermetacall:','meta: %s' % meta,'classname: %s' % classname,'supers: %s' % supers,'classdict: %s' % classdict,sep='')
return type.__call__(meta,classname,supers,classdict)
>class submeta(type,metaclass=supermeta):
def __new__(meta,classname,supers,classdict):
print('调用 submetanew:','meta: %s' % meta,'classname: %s' % classname,'supers: %s' % supers,'classdict: %s' % classdict,sep='')
return type.__new__(meta,classname,supers,classdict)
def __init__(class,classname,supers,classdict):
print('调用 submetainit:','class: %s' % class,'classname: %s' % classname,'supers: %s' % supers,'classdict: %s' % classdict,sep='')
print('初始化类对象:',list(class.__dict__.keys())
>class classa:pass
>class classb(classa,metaclass=submeta):
name='梯形图读取线'
def meth(self,arg):
pass 调用 supermetacall:
meta:
classname: classb
supers:
classdict:
调用 submetanew:
meta:
classname: classb
supers:
classdict:
调用 submetainit:
class:
classname: classb
supers:
classdict:
初始化类对象:'__module__', 'name', 'meth', '__doc__']
>cb=classb()
>cb.name
梯形图读取线'>>type(submeta)
>type(supermeta)
>type(classb)
>type(cb)
定义。描述:通过常规类模拟元类的元类,重载 call( 方法,调用子类的新方法,并显式调用 type() 以创建类对象以将值分配给客户端类。class supermeta:
def __call__(self,classname,supers,classdict):
class=self.__new__(classname,supers,classdict)
self.__init__(class,classname,supers,classdict)
passreturn class
class submeta(supermeta):
def __new__(self,classname,supers,classdict):
passreturn type(classname,supers,classdict)
def __init__(self,class,classname,supers,classdict):
通行证使用。
class classa:pass
class classb(classa,metaclass=submeta())pass
1)定义常规类supermeta模拟类的元类;
2) Supermeta 定义了 call(方法,调用子类 submeta new(和 init(method;
3) Supermeta 返回客户端类类
4)定义正则类submeta,继承supermeta,作为客户端类的元类;
5) submeta 的 new (方法,它显式调用 type() 方法来创建一个类对象,并返回分配给客户端类的值
6) submeta 的 init(方法,用于初始化类对象;
7)定义客户端类classb,指定元类metaclass=submeta()实例对象;
8)类协议自动调用实例对象submeta()的调用(方法),搜索supermeta的调用(方法),触发元类submeta的new和init方法
例
>>class supermeta:def __call__(self,classname,supers,classdict):
print('调用 supermetacall:','classname: %s' % classname,'supers: %s' % supers,'classdict: %s' % classdict,sep='')
class=self.__new__(classname,supers,classdict)
self.__init__(class,classname,supers,classdict)
return class
>class submeta(supermeta):
def __new__(self,classname,supers,classdict):
print('调用 submetanew:','classname: %s' % classname,'supers: %s' % supers,'classdict: %s' % classdict,sep='')
return type(classname,supers,classdict)
def __init__(self,class,classname,supers,classdict):
print('调用 submetainit:','class: %s' % class,'classname: %s' % classname,'supers: %s' % supers,'classdict: %s' % classdict,sep='')
print('初始化类对象:',list(class.__dict__.keys())
>class classa:pass
>class classb(classa,metaclass=submeta())
name='梯形图读取线'
def meth(self,arg):
pass 调用 supermetacall:
classname: classb
supers:
classdict:
调用 submetanew:
classname: classb
supers:
classdict:
调用 submetainit:
class:
classname: classb
supers:
classdict:
初始化类对象:'__module__', 'name', 'meth', '__doc__']
>cb=classb()
>cb.name
梯形图读取线'>>type(submeta)
>type(supermeta)
>type(classb)
>type(cb)