复习
上节课复习: 1、什么是元类 元类是我们自定义类的类,即我们用class定义的类本质 就是在实例化元类 class Foo: #Foo=元类('类名',(obejct),class_dic) pass obj=Foo() 2、为何用用元类+如何用? 2.1 控制class定义类的过程 class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): #控制逻辑 super().__init__(class_name,class_bases,class_dic) class Foo(object,metaclass=Mymeta): #Foo=Mymeta('Foo',(object,),{'x':1,....}) x=1 2.2 控制对象(指的就是Foo的对象)的产生过程 class Mymeta(type): def __call__(self,*args,**kwargs): obj=self.__new__(self) #self=Foo self.__init__(obj,*args,**kwargs) return obj class Foo(object,metaclass=Mymeta): #Foo=Mymeta(...) def __init__(self,x,y): self.x=x self.y=y obj=Foo(x=1,y=2) 今日内容: 1、单例模式的三种实现方式 2、异常处理
元类补充
class Mymeta(type): n=444 def __call__(self, *args, **kwargs): obj = self.__new__(self) # self=Foo # obj = object.__new__(self) # self=Foo self.__init__(obj, *args, **kwargs) return obj class A(object): n=333 # pass class B(A): n=222 # pass class Foo(B,metaclass=Mymeta): # Foo=Mymeta(...) n=111 def __init__(self, x, y): self.x = x self.y = y print(Foo.n) #查找顺序: #1、先对象层:Foo->B->A->object #2、然后元类层:Mymeta->type # print(type(object)) # obj=Foo(1,2) # print(obj.__dict__)
练习
class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): #控制类Foo的创建 # if class_dic.get('__doc__') is None or len(class_dic.get('__doc__').strip()) == 0: # raise TypeError('类中必须有文档注释,并且文档注释不能为空') # if not class_name.istitle(): # raise TypeError('类名首字母必须大写') super(Mymeta,self).__init__(class_name,class_bases,class_dic) def __call__(self, *args, **kwargs): #控制Foo的调用过程,即Foo对象的产生过程 obj = self.__new__(self) self.__init__(obj, *args, **kwargs) obj.__dict__={'_%s__%s' %(self.__name__,k):v for k,v in obj.__dict__.items()} #对象的属性变成隐藏属性 return obj class Foo(object,metaclass=Mymeta): # Foo=Mymeta(...) def __init__(self, name, age,sex): self.name=name self.age=age self.sex=sex obj=Foo('egon',18,'male') obj.name='alex' print(obj.__dict__)
单利模式
''' 1、什么是单例模式 单例模式:基于某种方法实例化多次得到实例是同一个 2、为何用单例模式 当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存,即同一个实例 3、如何用 ''' # 单例模式实现方式一: # import settings # # class Mysql: # __instacne=None # # def __init__(self,ip,port): # self.ip=ip # self.port=port # # @classmethod # def from_conf(cls): # if cls.__instacne is None: # cls.__instacne=cls(settings.IP,settings.PORT) # return cls.__instacne # # obj=Mysql('1.1.1.10',3306) # # obj1=Mysql.from_conf() # obj2=Mysql.from_conf() # obj3=Mysql.from_conf() # # print(obj1) # print(obj2) # print(obj3) # # obj4=Mysql('10.10.10.11',3307) # 单例模式实现方式二: # import settings # def singleton(cls): # cls.__instance=cls(settings.IP,settings.PORT) # def wrapper(*args,**kwargs): # if len(args) == 0 and len(kwargs) == 0: # return cls.__instance # return cls(*args,**kwargs) # return wrapper # # @singleton #Mysql=singleton(Mysql) #Mysql=wrapper # class Mysql: # def __init__(self,ip,port): # self.ip=ip # self.port=port # # # obj1=Mysql() #wrapper() # obj2=Mysql() #wrapper() # obj3=Mysql() #wrapper() # print(obj1 is obj2 is obj3) # print(obj1) # print(obj2) # print(obj3) # obj4=Mysql('1.1.1.4',3308) # print(obj4) # 单例模式实现方式三: import settings class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): #self=Mysql super(Mymeta,self).__init__(class_name,class_bases,class_dic ) self.__instance=self.__new__(self) #造出一个Mysql的对象 self.__init__(self.__instance,settings.IP,settings.PORT) #从配置文件中加载配置完成Mysql对象的初始化 # print(self.__instance) # print(self.__instance.__dict__) def __call__(self, *args, **kwargs): #self=Mysql if len(args) == 0 and len(kwargs) == 0: return self.__instance obj=self.__new__(self) self.__init__(obj,*args,**kwargs) return obj class Mysql(object,metaclass=Mymeta): #Mysql=Mymeta(...) def __init__(self,ip,port): self.ip=ip self.port=port obj1=Mysql() obj2=Mysql() obj3=Mysql() obj4=Mysql('10.10.10.11',3308) print(obj1) print(obj2) print(obj3) print(obj4)
面向对象相关知识
一 什么是面向对象的程序设计及为什么要有它,与面向过程的程序设计优劣对比以及应用场景 二 类和对象 3.1 什么是对象,什么是类 3.2 类的属性引用和实例化 3.3 对象的属性引用 3.4 对象之间的交互 3.5 类名称空间与对象/实例名称空间 三 继承与派生 4.1 什么是继承 4.2 继承与抽象(先抽象再继承) 4.3 继承与重用性 4.4 组合与重用性 四 4.6 抽象类 五 4.7 继承实现的原理(继承顺序:深度优先,广度优先) 4.8 子类中调用父类方法 六 多态与多态性 5.1 多态 5.2 多态性 七 封装 6.1 要封装什么 6.2 为什么要封装 6.3 封装分为两个层面 八 property,绑定到对象的方法,绑定到类的方法,解除绑定的方法 九 反射 十 isinstance,issubclass,__str__,__slots__ 十一 __del__ 十二 __call__,元类
重点代码
class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): #控制类Foo的创建 if class_dic.get('__doc__') is None or len(class_dic.get('__doc__').strip()) == 0: raise TypeError('类中必须有文档注释,并且文档注释不能为空') if not class_name.istitle(): raise TypeError('类名首字母必须大写') super(Mymeta,self).__init__(class_name,class_bases,class_dic) def __call__(self, *args, **kwargs): #控制Foo的调用过程,即Foo对象的产生过程 obj = self.__new__(self) self.__init__(obj, *args, **kwargs) obj.__dict__={'_%s__%s' %(self.__name__,k):v for k,v in obj.__dict__.items()} #对象的属性变成隐藏属性 return obj class Foo(object,metaclass=Mymeta): # Foo=Mymeta(...) def __init__(self, name, age,sex): self.name=name self.age=age self.sex=sex obj=Foo('egon',18,'male') obj.name='alex' print(obj.__dict__) ######### settings 内容 IP='1.1.1.1' PORT=3306 单利模式1 类方法 import settings class Mysql: __instance=None def __init__(self,ip,port): self.ip=ip self.port=port @classmethod def from_conf(cls): if cls.__instance is None: cls.__instance=cls(settings.IP,settings.PORT) return cls.__instance obj1=Mysql.from_conf() obj2=Mysql.from_conf() obj3=Mysql.from_conf() obj4=Mysql('10.10.10.10',3307) print(obj1) print(obj2) print(obj3) print(obj4) 单例模式2 装饰器 import settings def singleton(cls): _instance = cls(settings.IP,settings.PORT) def wrapper(*args,**kwargs): if len(args) == 0 and len(kwargs) == 0: return _instance return cls(*args,**kwargs) return wrapper @singleton class Mysql: def __init__(self,ip,port): self.ip=ip self.port = port obj1=Mysql() obj2=Mysql() obj3=Mysql() obj4=Mysql('2.2.2.2',3307) print(obj1) print(obj2) print(obj3) print(obj4) 单利模式3 元类方式 import settings class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): super(Mymeta,self).__init__(class_name,class_bases,class_dic) self.__instance=self.__new__(self) self.__init__(self.__instance,settings.IP,settings.PORT) def __call__(self, *args, **kwargs): if len(args) == 0 and len(kwargs) == 0: return self.__instance obj= self.__new__(self) self.__init__(obj,*args,**kwargs) return obj class Mysql(object,metaclass=Mymeta): def __init__(self,ip,port): self.ip=ip self.port=port obj1=Mysql() obj2=Mysql() obj3=Mysql() obj4=Mysql('2.2.2.2',3309) print(obj1) print(obj2) print(obj3) print(obj4)