1.元类:在python中一切皆对象,对象是由某一个类创建的。那么类也是一个对象,它是由其元类创建的一个对象,元类就相当于一个类的类(它的实例是一个类),当创建一个类时,若没有指定元类,将使用默认的元类type,类是type的一个对象。那么也可以自己创建一个类使得它的一个实例也是一个类。具有和type相同的功能,元类可以在生成类是对类进行一些操作。
2.一个类的组成可分为类名,类属性,父类集合。所以也可以是使用这些元素,手动使用type创建一个类。
形式:接受类的变量 = type(类名,tuple(父类集合),dict(属性))
3.元类的声明。
Class 类名(metaclass = 元类)。且具有遗传性,若某个类的父类是由某个元类创建的,那么该类也由该元类创建的。
4.创建一个简单元类
一个简单元类就是含有__new__方法(构造方法)的type子类。在构造方法中,将会调用type方法的构造方法,从而生成一个对象,该对象也就是元类所生成的类。
个人理解:
5.实例化由元类创建出来的类
实例化一个类,就是类名加上括号。既然类也是一个对象,那么类名加上括号也就是对象名加上括号。对象名加上括号将会调用__call__方法。一个类再实例化一个对象时,将会先调用构造方法,然后再调用__init__方法,对对象进行初始化。那么将会在__call__方法中取调用构造方法和初始化方法。
当不重写__call__方法时,将会调用type的__call__方法。
当重写__call__方法,在__call__方法调用type的__call__方法,将会是一样的结果。
也可以在__call__自己调用构造方法和初始化方法,这样可以对象生成前完成一些相关的操作。
简单运用:
将不是魔术方法的方法名改为大写。
class Metaclass(type):
def __new__(cls, name, super_tuple, attribute_dict):
# 用于存放修改后的数据
new_dict = {}
for key, value in attribute_dict.items():
# 判断是否为魔术方法,(不能判断自定义的__名称__方法)
if isinstance(key, str) and key[0:2] + key[-2:] != "____":
new_dict[key.upper()] = value
continue
new_dict[key] = value
del attribute_dict
# 调用type的构造方法,生成对象new,此时new也为类New
new = super().__new__(cls, name, super_tuple, new_dict)
return new
# def __call__(self, *args, **kwargs):
# pass
class New(metaclass=Metaclass):
def __new__(cls, *args, **kwargs):
return object.__new__(cls)
def __init__(self):
self.name = "可能飘了"
def get_name(self):
print(self.name)
def set_name(self):
self.name = "不可能飘了"
print(New.__dict__)
# 结果:{'__module__': '__main__',
# '__new__': <staticmethod object at 0x01FC9EF0>,
# '__init__': <function New.__init__ at 0x0205F618>,
# 'GET_NAME': <function New.get_name at 0x0205F660>,
# 'SET_NAME': <function New.set_name at 0x0205F6A8>,
# '__dict__': <attribute '__dict__' of 'New' objects>,
# '__weakref__': <attribute '__weakref__' of 'New' objects>,
# '__doc__': None}
创建单例类
class Mytype(type):
def __new__(cls, *args, **kwargs):
new = type.__new__(cls, *args, **kwargs)
new.new_class = None
return new
def __call__(self, get_name=None, *args, **kwargs):
if not self.new_class:
self.new_class = self.__new__(self, *args, **kwargs)
self.__init__(self.new_class, *args, **kwargs)
return self.new_class
class My_class(object, metaclass=Mytype):
def __init__(self):
self.name = self.__class__
new = My_class()
print(new.name)
new.name = "可能飘了"
print(My_class().name)
# 结果:
# <class '__main__.My_class'>
# 可能飘了