python-study-25

复习

上节课复习:
    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、异常处理
View Code

元类补充

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__)
View Code

练习

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__)
View Code

单利模式

'''
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)
View Code

面向对象相关知识

一 什么是面向对象的程序设计及为什么要有它,与面向过程的程序设计优劣对比以及应用场景
二 类和对象
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__,元类
View Code

重点代码

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)
View Code

猜你喜欢

转载自www.cnblogs.com/xujinjin18/p/9254143.html