类的内置方法和单例模式

一、什么是类的内置方法?

凡是在类内部定义,以__开头__结尾的方法,都是类的内置方法,也称之为魔法方法。

类的内置方法,会在某种条件满足下自动触发。

内置方法如下:

__new__: 在__init__触发前,自动触发。 调用该类时,内部会通过__new__产生一个新的对象。

__init__: 在调用类时自动触发。 通过产生的对象自动调用__init__()

 

class Demo:

    ## 条件: __init__: 在调用类时自动触发。
    def __init__(self):
        print('此处是__init__方法的执行')

    ## 1、条件: __new__: 在__init__触发前,自动触发。
    def __new__(cls, *args, **kwargs):
        print('此处是__new__方法的执行')

        ## python内部通过object调用内部的__new__实现产生一个空的对象  ---> 内存地址
        return object.__new__(cls, *args, **kwargs)

obj = Demo()
#此处是__new__方法的执行
#此处是__init__方法的执行
#类内部的方法无关位置
    #2、__getattr__: 在 “对象.属性” 获取属性时,若 “属性没有” 时触发。
    def __getattr__(self, item):
        print('此处是__getattr__方法的执行')
        print(item)   # x

        return '想要返回的值'
obj = Demo()
obj.x   #属性x 此时不存在
#结果:此处是__getattr__方法的执行  x
print(obj.x)  #结果:想要返回的值
    #3、条件: __getattribute__: 在 “对象.属性” 获取属性时,无论 "属性有没有" 都会触发。
    def __getattribute__(self, item):
        print('此处是__getattribute__方法的执行')
        # print(item)   #x
        return 'z'

obj = Demo()
# obj.x
#结果: 此处是__getattribute__方法的执行  x
print(obj.x)  #z

##注意: 只要__getattr__ 与 __getattribute__ 同时存在类的内部,只会触发__getattribute__。
    # 4、条件: 当 “对象.属性 = 属性值” , 添加或修改属性时触发
    def __setattr__(self, key, value):
print('此处是__setattr__方法的执行')
# print(key, value)
print(self.__dict__) #{}
self.__dict__[key] = value #obj.x = 10
print(self.__dict__) #{'x': 10}

obj = Demo()
obj.x = 10
    ##5、条件: 在调用对象 “对象 + ()” 时触发。
    def __call__(self, *args, **kwargs):
        print('此处是__call__方法的执行')
        return 123

obj = Demo()
obj()
#此处是__call__方法的执行
    ##6、条件: 在打印对象时触发。该方法必须要有一个 “字符串” 返回值。
    def __str__(self):
        print('此处是__str__方法的执行')
        return '1'

obj = Demo()
print(obj)
#此处是__str__方法的执行
#1
    ##7、在对象通过 “对象[key]” 获取属性时触发。
    def __getitem__(self, item):
        print('此处是__getitem__方法的执行')
        print(item)
        return self.__dict__[item]
obj = Demo()
obj['x']
print(obj['x'])  #KeyError: 'x'
    ##8、在对象通过 “对象[key]=value值” 设置属性时触发。
    def __setitem__(self, key, value):
        print('此处是__setitem__方法的执行')
        # print(key, value)
        self.__dict__[key] = value

obj = Demo()
obj['x'] = 20
print(obj.x)
#此处是__setitem__方法的执行
#20

 

 

二、单例

指的是在确定类中的属性与方法不变时,需要反复调用该类,产生不同的对象,会产生不同的内存地址,造成资源浪费。

让所有类在实例化时,指向同一个内存地址,称之为单例模式。

单例的优点:

节省内存空间。

方式一:通过@classmethod实现

class MySQL:

    tag = None

    def __init__(self, x, y):
        self.x = x
        self.y = y

    @classmethod
    def singleton(cls, x, y):   # 单例方法 ---》 类方法

        ## 判断tag中若没有值,证明没有对象
        if not cls.tag:

            ## 产生一个对象并返回
            obj = cls(x, y)
            ## None ---> obj
            cls.tag = obj
        # 若tag中有值,证明对象已经存在,则直接返回该对象
        return cls.tag

    def start_mysql(self):
        print('启动mysql')

    def close(self):
        print('关闭mysql')


#调用类的方法
obj1 = MySQL.singleton(10, 20)
print(obj1)  #<__main__.MySQL object at 0x00000000029B1CF8>
obj2 = MySQL.singleton(10, 20)
print(obj2)  #<__main__.MySQL object at 0x00000000029B1CF8>

 方式二:通过__new__实现:

class Singleton:

    __instance = None

    def __new__(cls, *args, **kwargs):

        if not cls.__instance:

            #造一个空对象
            cls.__instance = object.__new__(cls)
        return cls.__instance


obj1 = Singleton()
obj2 = Singleton()
obj3 = Singleton()
print(obj1)
print(obj2)
print(obj3)

 

posted @ 2019-11-29 16:13  小猪皮蛋  阅读(129)  评论(0编辑  收藏  举报