类的魔法方法和部分单例模式

天大地大妈咪最大 提交于 2019-12-06 02:37:28

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

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

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

内置方法如下:

__ new __ : 在__ init __ 触发前触发,调用该类时会通过 __ new __ 产生一个新的对象

__ init __ : 在调用类时,自动触发。通过产生的对象自动调用 __ init __

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

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

内置方法如下:
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 'tank is very very handsome!!!'

 条件: __getattribute__: 在 “对象.属性” 获取属性时,无论 "属性有没有" 都会触发。
 def __getattribute__(self, item):
     print(item, '<-----打印属性名字')
     print(self.__dict__)
     return self.__dict__[item]
     注意: 此处不能通过 对象.属性,否则会产生递归调用,程序崩溃
     getattr: 内部调用了 ----> __getattribute__
     return getattr(self, item)

 注意: 只要__getattr__ 与 __getattribute__ 同时存在类的内部,只会触发__getattribute__。

 条件: 当 “对象.属性 = 属性值” , 添加或修改属性时触发
def __setattr__(self, key, value):  # key---> 对象.属性名  value ---》 属性值
    print('此处是__setattr__方法的执行')
    print(key, value)

     出现递归
     self.key = value
     print(self.__dict__)

     此处是对 对象的名称空间 ---》 字典进行操作
    self.__dict__[key] = value

 条件: 在调用对象 “对象 + ()” 时触发。
 def __call__(self, *args, **kwargs):
     print('此处是__call__方法的执行')

      调用对象时返回的值
     return [1, 2, 3, 4, 5]

 条件: 在打印对象时触发。
 注意: 该方法必须要有一个 “字符串” 返回值。
 def __str__(self):
     print('此处是__str__方法的执行')
     return '111'

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

 在对象通过 “对象[key]=value值” 设置属性时触发。
 def __setitem__(self, key, value):
     print('此处是__setitem__方法的执行')
     print(key, value)
     print(self.__dict__)
     self.key = value  # {'key': value}
     print(self.__dict__)
     self.__dict__[key] = value

print(type)
demo_obj = Demo() # 此处是__init__方法的执行
print(demo_obj.x, '<----想要返回的值...')
demo_obj.x = 10
print(demo_obj.x, '<----属性有时不会触发__getattr__...')
原来设置属性时,会自动触发父类中的__setattr__,内部为对象添加x属性,值为20
demo_obj.y = 20

demo_obj.y = 30

print(demo_obj.__dict__)
res = demo_obj()
print(res)
print(demo_obj)
list1 = list([1, 2, 3, 4, 5])
print(list1)
print(demo_obj.x)
print(demo_obj, '<----- 打印的对象')
print(demo_obj['x'])
demo_obj['y'] = 300
print(demo_obj.y)

单例模式

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

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

    单例模式的优点:
    节省内存空间
'''


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


fool_obj1 = Foo(1, 2)
print(fool_obj1.__dict__)
print(fool_obj1)
fool_obj2 = Foo(1, 2)
print(fool_obj2.__dict__)
print(fool_obj2)


# {'x': 1, 'y': 2}
# <__main__.Foo object at 0x000001C92DFFDCC0>
# {'x': 1, 'y': 2}
# <__main__.Foo object at 0x000001C92E19F438>


# 单例模式
# 1.通过classmethod实现
class MYSQL:
    # 首先设置一个默认值,用于判断对象是否存在,对象不存在证明是None
    # __instance是类的属性,可以由类来调用
    __instance = None

    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)
            cls.__instance = obj
        # 若__instance中有值,证明对象已经存在,则直接返回该对象
        return cls.__instance

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

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


obj1 = MYSQL.singleton('123.3.10.2', 3306)
print(obj1.__dict__)
print(obj1)
obj2 = MYSQL.singleton('14.21.20', 3306)
print(obj2.__dict__)
print(obj2)

obj1.start_mysql()
obj2.start_mysql()


结果:
{'x': 1, 'y': 2}
<__main__.Foo object at 0x000002AC7C7BF400>
{'x': 1, 'y': 2}
<__main__.Foo object at 0x000002AC7F806DD8>
{'host': '123.3.10.2', 'port': 3306}
<__main__.MYSQL object at 0x000002AC7F822240>
{'host': '123.3.10.2', 'port': 3306}
<__main__.MYSQL object at 0x000002AC7F822240>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!