python 之元类

定义类的两种方法:

  1.class定义

  2.type(类名,类的基类们,类的名称空间)

# 定义类的三要素:类名、基类、名称空间
class_name = 'Chinese'
class_bases = (object,)
class_body = """
country = 'China'

def __init__(self,namem,age):
    self.name=namem
    self.age=age
    
def talk(self):
    print('%s is talking'%self.name)
    
"""
class_dic = {}
exec(class_body,globals(),class_dic)
print(class_dic)

Chinese = type(class_name,class_bases,class_dic)

 

自定义元类控制类的创建(在元类的init方法里做控制):

class Mymeta(type):
    '''
    自定义的元类
    '''
    def __init__(self,class_name,class_bases,class_dic):
        if not class_name.istitle():
            raise TypeError('类名的首字母必须大写')
        # 不写注释时,则无__doc__
        if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
            raise TypeError('必须有注释,且注释不能为空')
        super(Mymeta,self).__init__(class_name,class_bases,class_dic)


class Chinese(object,metaclass=type):
    country = 'China'
    def __init__(self, namem, age):
        self.name = namem
        self.age = age

    def talk(self):
        print('%s is talking' % self.name)

# Chinese首字母不大写的话会报异常
class Chinese1(object,metaclass=Mymeta):
    '''
    注释
    '''
    country = 'China'
    def __init__(self, namem, age):
        self.name = namem
        self.age = age

    def talk(self):
        print('%s is talking' % self.name)

# Chinese2 = Mymeta(class_name,class_bases,class_dic)

 

自定义元类控制类的实例化(重写call方法):

class Mymeta(type):
    def __init__(self,class_name,class_bases,class_dic):
        if not class_name.istitle():
            raise TypeError('类名的首字母必须大写')
        # 不写注释时,则无__doc__
        if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
            raise TypeError('必须有注释,且注释不能为空')
        super(Mymeta,self).__init__(class_name,class_bases,class_dic)
        self.__instance = None
    
# 实现的单例可与sigleton装饰器的比较下
def __call__(self, *args, **kwargs): if not self.__instance: obj = object.__new__(self) self.__init__(obj) self.__instance = obj return self.__instance class Mysql(object,metaclass=Mymeta): ''' 元类控制实例化行为 ''' def __init__(self): self.host = '127.0.0.1' self.port = 3306 def conn(self): pass def execute(self): pass obj1 = Mysql() obj2 = Mysql() print(obj1 == obj2)

 

posted @ 2018-03-06 18:00  Claire_xu  阅读(155)  评论(0编辑  收藏  举报