python-元类

元类:

         产生类的类称元类,所有用class定义的类,它们的元类是type。

知识:exec()方法

1、        字符串形式的命令

2、        全局作用域(字典形式)不指定,默认使用globals()

3、        局部作用域(字典形式)不指定,默认使用locals()

Python 中一切皆对象(统一的使用的方式):

       对象的用法:(模块、对象、函数、类等)

1、        都可以被引用 x =obj

2、        都可以当函数的参数传入

3、        都可以当函数返回值

4、        都可以当做容器类型:容器类型【list tuple dict set 】

 

创建类的两种方式

一、使用class关键字(常用)

 

# 方法一 class 定义类
class Chinese:
    country = 'china'
    def __init__(self,name,age):
        self.name=name
        self.age=age

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

c1=Chinese('老黄',19)

c1.talk()
用class定义类

 

二、自定义模拟class创建类的过程:

用type 定义类 的三要素

1、类名 2、类的父类、3、类的名称空间

# 方法二 type 定义类
# 用type 定义类的三要素
# 1、类名
# 2、类的父类
# 3、类体

# 类的三要素 类名、 类的基类、类的名称空间
class_name = 'Chinese1'  # 1、类名
class_bases=(object,)   # 2、类的基类
class_body='''
country = 'china'

def __init__(self, name, age):
    self.name = name
    self.age = age

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

'''

class_dic={}            # 3、类的名称空间
exec(class_body,globals(),class_dic)

Chinese1=type(class_name,class_bases,class_dic )

ch1=Chinese1('老黄',20)
print(Chinese1,ch1.name,ch1.age)
用type定义类

 

三、自定义元类的用法:

  1、通过元类,控制类的创建行为:

    eg:规定创建类时首字母大写、规定类中有注释等等。

#通过元类来控制类的定义行为:eg:首字母大写,要有注释
class Mymeta(type):
    def __init__(self,class_name,class_bases,class_dic):
        if '__doc__' not in class_dic or not class_dic.get('__doc__').strip():
            raise TypeError('必须为类指定文档注释')

        if not class_name.istitle():
            raise TypeError('类名首字母必须大写')

        super(Mymeta, self).__init__(class_name, class_bases, class_dic)


class Chinese(object,metaclass=Mymeta):
    """
    chinese 类
    """
    country = 'china'

    def __init__(self, name, age):
        self.name = name
        self.age = age

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



c1 = Chinese('老黄', 19)

c1.talk()
print(Chinese,c1.name,c1.age)
通过元类控制类定义的行为

  2、通过元类控制实例化行为:(单例模式)
  

#通过元类来控制实例的实例化:eg:多个实例实例化时引用一个实例
class Mymeta(type):
    def __init__(self,name,bases,dic): #定义类Mysql时就触发
        self.__instance=None
        super().__init__(name,bases,dic)

    def __call__(self, *args, **kwargs): #Mysql(...)时触发

        if not self.__instance:
            self.__instance=object.__new__(self) #产生对象
            self.__init__(self.__instance,*args,**kwargs) #初始化对象
            #上述两步可以合成下面一步
            # self.__instance=super().__call__(*args,**kwargs)

        return self.__instance
class Mysql(metaclass=Mymeta):
    def __init__(self,host='127.0.0.1',port='3306'):
        self.host=host
        self.port=port


obj1=Mysql()
obj2=Mysql()

print(obj1 is obj2)
单例模式

 

posted @ 2018-05-10 22:12  OYxing  阅读(560)  评论(0编辑  收藏  举报