zoukankan      html  css  js  c++  java
  • 类的魔法方法和部分单例模式

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

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

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

    内置方法如下:

    __ 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>
    
    
  • 相关阅读:
    剑指offer:二维数组的查找
    安卓突击:绘制图像
    安卓突击:绘制图形和文本
    Android突击:定制控件
    Android突击:PanelLayout的实现
    POJ 1426 Find The Multiple
    POJ 2251 Dungeon Master
    event.target的认识
    JS延迟加载
    jquery中position 和offset的区别
  • 原文地址:https://www.cnblogs.com/godlover/p/11957796.html
Copyright © 2011-2022 走看看