元类:
产生类的类称元类,所有用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创建类的过程:
用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)
三、自定义元类的用法:
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)