面向对象高级

面向对象高级

一、类的内置方法(魔法方法)

  • 代码
'''
类的内置方法(魔法方法):
    凡是在类内部定义,以__开头__结尾的方法,都是类的内置方法,也称之为魔法方法。

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


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

'''

class Demo(object):
    
    def __init__(self):
        object.__setattr__(self, key, {})

    # #触发条件:__new__: 在__init__触发前,自动触发
    #
    # def __new__(cls, *args, **kwargs):
    #     print('此处是__new__方法的执行')
    #     #python内部通过object调用内部的__new__实现产生一个空的对象 ---> 内存地址
    #     return object.__new__(cls, *args, **kwargs)
    #
    # #触发条件:__init__:在调用类时自动执行
    # def __init__(self):
    #     print('此处是__init__方法的执行')
    #
    # #__getattr__:在“对象.属性”获取属性时,若“属性没有”时触发
    # def __getattr__(self, item):
    #     print('此处是__getattr__方法的执行')
    #     print(item)
    #
    #     #return 想要返回的值
    #     return 'yafeng is very handsome!!!'
    #
    # #__getattribute__:在“对象.属性”获取属性时,无论“属性有没有”都会触发
    # def __getattribute__(self, item):
    #     print(item, '打印属性的名字')
    #     print('此处是__getattribute__方法')
    #
    #     #print(self.__dict__)
    #     #return self.__dict__[item]
    #     #注意:此处不能通过 对象.属性 , 否则会产生递归调用,程序崩溃
    #     #getattr:内部调用了--->__getattribute__
    #     # return getattr(self, item)
    #
    # #__setattr__:当对象.属性=属性值 ,添加或修改属性时触发
    def __setattr__(self, key, value):  #key--->对象.属性名  value--->属性值
        print('此处是__setattr__方法的执行')
        print(key, value)

    #     #出现递归     # 解决方法:继承一个基类,在基类中,去设置一个key属性
    #     #self.key = value
    #     #print(self.__dict__)
    #
    #     #此处是对 对象的名称空间 ---> 字典进行操作
    #     self.__dict__[key] = value

    #在打印对象时触发
    # #注意:该方法必须要有一个“字符串”返回值
    # def __str__(self):
    #     print('此处是__str__方法的执行')
    #     return 'yafeng 666'
    #
    # #条件:在调用对象 “对象+()”时触发
    # def __call__(self, *args, **kwargs):
    #     print('此处是__call__方法的执行')
    #
    #     #调用对象的返回值
    #     return [1, 2, 3, 4]

    #在对象通过 “对象[key]”属性时触发。
    def __getitem__(self, item):
        print('此处是__getitem__方法执行')
        print(item)
        return self.__dict__[item]

    #在对象通过“对象[key]=value值” 设置属性时触发
    def __setitem__(self, key, value):
        print(key, value)
        self.__dict__[key] = value





demo_obj = Demo()
#此处是__new__方法的执行
#此处是__init__方法的执行
# print(demo_obj.x)
#此处是__getattr__方法的执行
# x
# yafeng is very handsome!!!

# print(demo_obj.x)
# x 打印属性的名字
# 此处是__getattribute__方法

demo_obj.x = 10
#此处是__setattr__方法的执行


# print(demo_obj)
#此处是__str__方法的执行
# yafeng 666


# demo_obj()
# print(demo_obj())
#此处是__call__方法的执行
# [1, 2, 3, 4]

# demo_obj['x']
# print(demo_obj['x'])
#此处是__getitem__方法执行
# x


demo_obj['y'] = 300
print(demo_obj['y'])
# y
# 300

二、单例模式

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

    让所有类在实例化时,指向同一个内存地址,称之为单例模式。  ----> 无论产生多个对象,都会指向 单个 实例。

    - 单例的优点:
        节省内存空间。
'''

#
# class Foo:
#     def __init__(self, x, y):
#         self.x = x
#         self.y = y


# foo_obj1 = Foo(10, 20)
# print(foo_obj1.__dict__)
# print(foo_obj1)
#
# foo_obj2 = Foo(10, 20)
# print(foo_obj2.__dict__)
# print(foo_obj2)


'''
单例模式: (面试让你手撸,一定要背下来。)
    1.通过classmethod
    2.通过装饰器实现
    3.通过__new__实现
    4.通过导入模块时实现
    5.通过元类实现。
'''
import settings


# 通过classmethod
class MySQL:

    # 一个默认值,用于判断对象是否存在, 对象不存在证明值是None
    # __instance是类的属性,可以由类来调用
    __instance = None  #  ---》 执行到代码的57行 ---》 obj
    # __instance = obj

    def __init__(self, host, port):
        self.host = host
        self.port = port

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

        # 判断__instance中若没有值,证明没有对象
        if not cls.__instance:
            # 产生一个对象并返回
            obj = cls(host, port)
            # None ---> obj
            cls.__instance = obj

        # 若__instance中有值,证明对象已经存在,则直接返回该对象
        return cls.__instance

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

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


obj1 = MySQL.singleton(settings.HOST, settings.PORT)
print(obj1)
obj2 = MySQL.singleton(settings.HOST, settings.PORT)
print(obj2)


# obj1 = MySQL(settings.HOST, settings.PORT)
# obj2 = MySQL(settings.HOST, settings.PORT)
# obj3 = MySQL(settings.HOST, settings.PORT)
# print(obj1)
# obj1.start_mysql()
# obj1.close()
#
# print(obj2)
# obj2.start_mysql()
# obj2.close()
#
# print(obj3)
# obj3.start_mysql()
# obj3.close()

posted @ 2019-11-29 18:16  alen_zhan  阅读(129)  评论(0编辑  收藏  举报
返回顶部