面向对象高级
一、类的内置方法(魔法方法)
'''
类的内置方法(魔法方法):
凡是在类内部定义,以__开头__结尾的方法,都是类的内置方法,也称之为魔法方法。
类的内置方法,会在某种条件下自动触发。
内置方法如下:
__new__:在__init__触发前,自动触发,调用该类时,内部会通过__new__产生一个新的对象
__init__:在调用类时自动触发。通过产生的对象自动调用__init__()
'''
class Demo(object):
# #触发条件:__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)
# #出现递归
# #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()