1. Control in the metaclass to change the data attributes of the custom class to uppercase
class Mymeta(type):
def __new__(cls,x,y,z):#其中x为类名,y为基类,z为名称空间
class_dic = {}
for k,v in z.items():
if not callable(v) and not k.startswith('__'):
class_dic[k.upper()] = v
else:
class_dic[k] = v
return type.__new__(cls,x,y,class_dic)
class People(metaclass = Mymeta):
country = 'China'
tag = '龙的传人'
def __init__(self,name,age):
self.name = name
self.age = age
def say(self):
print('<%s:%s>'%(self.name,self.age))
print(People.__dict__)
2. The __init__ method is not required to control the custom class in the metaclass
1) Metaclasses help them to create objects and initialize operations;
2) The parameter must be in the form of keyword during instantiation, otherwise an exception is thrown TypeError: must use keyword argument
3) The key is the attribute of the object generated by the user-defined class, and all attributes become uppercase
class Mymeta(type):
def __call__(cls,*args,**kwargs):
if len(args):
raise TypeError('must use keyword argument')
obj = object.__new__(cls)
for k,v in kwargs.items():
obj.__dict__[k.upper()] = v
return obj
class People(metaclass = Mymeta):
country = 'China'
tag = '龙的传人'
def singing(self):
print('[{}]正在唱: 万里长城永不倒。。。'.format(self.NAME))
tank = People(name = 'tank', age = 18)
print(tank.__dict__)
tank.singing()
3. In the metaclass, all attributes related to the objects generated by the custom class are hidden attributes.
class Mymeta(type):
def __call__(self,*args,**kwargs):
people_obj = object.__new__(self)
self.__init__(people_obj,*args,**kwargs)
people_obj.__dict__={
'_%s__%s'%(self.__name__,k):v for k,v in people_obj.__dict__.items()
}
return people_obj
class People(metaclass = Mymeta):
country = 'China'
tag = '龙的传人'
def __init__(self,name,age):
self.name = name
self.age = age
def singing(self):
print('[{}]正在唱:万里长城永不倒。。。'.format(self._People__name))
tank = People('tank',84)
tank.singing()
print(tank.tag)
4. Implement the singleton pattern based on metaclasses
import settings
class Mymeta(type):
def __init__(self,name,bases,dic):
self.__instance = object.__new__(self)
self.__init__(self.__instance,settings.HOST,settings.PORT)
super().__init__(name,bases,dic)
def __call__(self,*args,**kwargs):
if args or kwargs:
obj = object.__new__(self)
self.__init__(obj,*args,**kwargs)
return obj
return self.__instance
class Mysql(metaclass=Mymeta):
def __init__(self,host,port):
self.host = host
self.port = port
obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
print(obj1 is obj2 is obj3)