什么是元类
元类是类的类,是类的模板,用来控制如何创建类的,正如类是创建对象的模板一样,type
是python
的一个内建元类,用来直接控制生成类,python
中任何class
定义的类其实是type
类实例化的对象
class MyClass(object):
pass
'''type就是所有类默认的元类'''
obj = MyClass()
print(type(obj))
# <class '__main__.MyClass'>
print(type(MyClass))
# <class 'type'>
如何产生类
- 利用
class
关键字
# class 类名
class MyClass(object):
pass
print(MyClass)
# <class '__main__.MyClass'>
type
元类
# type(类名, 父类, 类的名称空间)
res = type('MyClass', (), {})
print(res)
# <class '__main__.MyClass'>
基本使用
class MyTypeClass(type):
def __init__(cls, cls_name, cls_bases, cls_dict): # cls用来接收类
if not cls_name.istitle():
raise Exception("类名的首字母必须大写")
super.__init__(cls_name, cls_bases, cls_dict)
# print(cls, cls_name, cls_bases, cls_dict)
# <class '__main__.MyClass'> MyClass () {'__module__': '__main__', '__qualname__': 'MyClass', 'student': 'kevin'}
# 元类是不能通过继承的方式直接指定的,需要关键字metaclass
class MyClass(metaclass=MyTypeClass):
student = 'kevin'
print(type(MyClass))
# <class '__main__.MyTypeClass'>
class a(metaclass=MyTypeClass):
pass
# Exception: 类名的首字母必须大写
元类是不能通过继承的方式直接指定的,需要关键字metaclass
进阶操作
对象加括号会自动执行产生该对象的类里面的__call__
。类加括号会执行元类的里面的__call__
class MyTypeClass(type):
def __call__(self, *args, **kwargs):
print('执行__call__')
super().__call__(*args, **kwargs)
class MyClass(metaclass=MyTypeClass):
def __init__(self, name):
print('执行__init__')
self.name = name
obj = MyClass('kevin')
# 执行__call__
# 执行__init__
# 定制对象的产生过程
class MyTypeClass(typ):
def __call__(self, *args, **kwargs):
# print('__call__ run')
# print(args,kwargs)
if args:
raise Exception('必须全部采用关键字参数')
super().__call__(*args, **kwargs)
class MyClass(metaclass=MyTypeClass):
def __init__(self, name):
# print('__init__ run')
self.name = name
"""强制规定:类在实例化产生对象的时候 对象的独有数据必须采用关键字参数"""
obj = MyClass(name='kevin')