zoukankan      html  css  js  c++  java
  • day19-Python运维开发基础(类的魔术方法)

    1. __new__魔术方法

    # ###  __new__ 魔术方法
    '''
        触发时机:实例化类生成对象的时候触发(触发时机在__init__之前)
        功能:控制对象的创建过程
        参数:至少一个cls接受当前的类,其他根据情况决定
        返回值:通常返回对象或None
    '''
    
    class MyClass2():
        b = 2
    obj2 = MyClass2()
    
    # (1) 基本语法
    """
    借助object父类中的__new__魔术方法,创建对象
    需要传递cls这个参数,代表的是本类,为本类创建对象,进行返回
    """
    class MyClass():
        a = 1
        def __new__(cls):
            print(cls) # <class '__main__.MyClass'>
            # 借助父类object,里面的__new__魔术方法创建对象
            # 1.返回本对象
            return object.__new__(cls)
            # 2.返回其他类的对象
            # return obj2
            # 3.不返回任何对象
            # return None
            
            
    obj = MyClass()    
    print(obj)    
    # 返回本对象
    # print(obj.a)
    # 返回其他类对象
    # print(obj.b)
    
    # (2) 验证__new__和__init__两个方法的触发时间
    """
    __new__  用来创建对象
    __init__ 用来初始化对象的
    先创建在初始化
    __new__ 触发时机快于__init__
    """
    
    class MyClass():
        def __new__(cls):
            print(1)
            return object.__new__(cls)
    
        def __init__(self):
            print(2)    
            
    obj = MyClass()
    
    # 传一个参数的情况
    class MyClass():
        def __new__(cls,name):
            return object.__new__(cls)
    
        def __init__(self,name):
            self.name = name
            
    obj = MyClass("周永玲")
    
    # 传多个参数的情况
    class MyClass():
        # 多个参数下,用收集参数来保证形参实参一一对应
        def __new__(cls,*args,**kwargs):
            return object.__new__(cls)
            
        def __init__(self,name,skin,age):
            self.name = name
            self.skin = skin
            self.age = age
    obj = MyClass("周玲玲","绿色",108)
    print(obj.name)
    
    # 注意点:
    """
    如果__new__返回的不是自己本类的对象,不会触发构造方法__init__
    """
    class MyClass():
    
        def __new__(cls,*args,**kwargs):
            print("__new__被触发")
            return obj2
            
        def __init__(self):
            print("__init__构造方法被触发")
    obj = MyClass()
    __new__魔术方法 示例代码
    # ### 单态模式 : 无论实例化对象多少次,都有且只有一个对象
    
    # (1) 基本语法
    """为了节省空间,加快效率,提出单态模式"""
    class Singleton():
        __obj = None
        def __new__(cls):
            if cls.__obj is None:
                cls.__obj = object.__new__(cls)
            return cls.__obj
    
    """
    第一次实例化的时候,cls.__obj is None 返回True
    执行object.__new__(cls) 返回对象 让cls.__obj接受对象
    return 该对象
    
    第二次实例化的时候,cls.__obj is None 返回False
    return cls.__obj 内存中堆空间存放的对象返回
    
    第三次实例化的时候,cls.__obj is None 返回False
    return cls.__obj 内存中堆空间存放的对象返回
    
    以后 .. 每次进行实例化的对象,都是第一次存储的那个对象
    就实现了无论实例化几次,都返回同一个对象;
    """
    
    obj1 = Singleton()
    obj2 = Singleton()
    obj3 = Singleton()
    print(obj1,obj2,obj3)
    print(obj1 is obj2)
    
    # (2) 单态模式 + 构造方法
    class Singleton():
        __obj = None
        def __new__(cls,*args,**kwargs):
            if cls.__obj is None:
                cls.__obj = object.__new__(cls)
            return cls.__obj 
    
        def __init__(self,name):
            self.name = name
    
    obj1 = Singleton("李诗韵")
    obj2 = Singleton("黄乐锡")
    print(obj1.name)
    print(obj2.name)
    
    """
    
    第一次实例化的时候, self.name = 李诗韵
    第一次实例化的时候, 返回的是第一次实例化出来的对象
    将该对象以前的name属性 从李诗韵改成黄乐西
    self.name = 黄乐西
    
    打印 obj1.name  obj2.name 都是黄乐西
    
    """
    单态模式 示例代码

    2. 类的魔术方法

     

    # ### 魔术方法 __del__ (析构方法)
    '''
        触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.所有对象被del的时候]
        功能:对象使用完毕后资源回收
        参数:一个self接受对象
        返回值:无
    '''
    
    # (1) 基本使用
    class Dog():
        def __init__(self,name):
            self.name = name
            
        def eatmeat(self):
            print("小狗喜欢吃肉包子")
        
        def __del__(self):
            print("析构方法被触发")
    
    # (1)页面执行完毕回收所有变量
    obj = Dog("詹姆斯·蛋蛋")
    obj.eatmeat()
    
    # (2)所有对象被del的时候
    """
    两个变量指向同一个对象,其中删除obj这个变量的指向关系,
    还有一个变量在指向该对象,所以对象没有被删除,不能够触发析构方法__del__
    """
    obj2 = obj
    print("===start===")
    del obj
    # del obj2
    print("===end====")
    
    # (3)读取文件操作
    import os
    """
    fp = open("文件名",mode="r",encoding="utf-8")
    res = fp.read()
    fp.close()
    """
    class ReadFile():
        # 创建对象
        def __new__(cls,filename):
            if os.path.exists(filename):
                return object.__new__(cls)
            else:            
                return print("文件不存在")
        # 打开文件     
        def __init__(self,filename):
            self.fp = open(filename,mode="r",encoding="utf-8")
            
        # 读取文件
        def readfile(self):
            res = self.fp.read()
            return res
        
        # 关闭文件
        def __del__(self):
            self.fp.close()
    
    obj = ReadFile("ceshi.txt")
    res = obj.readfile()
    print(res)
    __del__析构方法 示例代码
    # ###__call__ 魔术方法
    '''
        触发时机:把对象当作函数调用的时候自动触发
        功能: 模拟函数化操作
        参数: 参数不固定,至少一个self参数
        返回值: 看需求
    '''
    # (1) 基本语法
    class MyClass():
        def __call__(self):
            print("call方法被触发")
            
    obj = MyClass()
    obj()
    
    # (2) 可以使用__call__统一调用方法,[模拟洗衣服的过程]
    class Wash():
        def __call__(self,something):
            print("这是{}方法".format(something))
            self.step1()
            self.step2()
            self.step3()
            return "洗完了"
    
        def step1(self):
            print("把衣服扔洗衣机里,把洗衣粉扔洗衣机里,搅拌")
        
        def step2(self):
            print("加水,启动开关,把关门上")
            
        def step3(self):
            print("把衣服拿出来,晒一晒")
    obj = Wash()
    """
    # 方法一
    obj.step1()
    obj.step2()
    obj.step3()
    """
    # 方法二
    # obj()
    res = obj("洗衣服")
    print(res)
    
    
    # 模拟int方法,自定义类
    import math
    """bool int float 字符串"""
    class MyInt():
                        
        def myfunc(self,num,sign=1):
            # print(num)
            # print(sign)
            res = num.lstrip("0")
            if res == "":
                return 0        
            return eval(res) * sign
    
        def __call__(self,n):
        
            # 判断是不是bool
            if isinstance(n,bool):
                if n == True:
                    return 1
                else:
                    return 0
                    
            # 判断是不是int
            elif isinstance(n,int):
                return n
                
            # 判断是不是float
            elif isinstance(n,float):
                if n > 0:
                    return math.floor(n)
                else:
                    return math.ceil(n)
                    
            # 判断是不是字符串
            elif isinstance(n,str):
                
                # 判断是否带符号 + - 
                if (n[0] == "+" or n[0] == "-") and n[1:].isdecimal():                
                    sign = None
                    # 获取符号
                    if n[0] == "+":
                        sign = 1
                    elif n[0] == "-":
                        sign = -1
                    return self.myfunc(n[1:],sign)
                # 判断是否是纯数字字符串
                elif n.isdecimal():
                    return self.myfunc(n)
                else:
                    return "老弟,这个东西算不了."
                    
            else:
                return "脑弟,这个算不了"
                
    
    myint = MyInt()
    res = myint(True)
    res = myint(-19.89)
    # res = myint("-abcddfdf")
    # res = myint([1,2,3])
    print(res,type(res))
    __call__魔术方法 示例代码
    # ### __str__ 魔术方法
    '''
        触发时机: 使用print(对象)或者str(对象)的时候触发
        功能:     查看对象
        参数:     一个self接受当前对象
        返回值:   必须返回字符串类型
    '''
    
    class Cat():
        gift = "卖萌,喵喵喵"
        def __init__(self,name):
            self.name = name
            
        def cat_info(self):
            return "小猫的名字{},小猫的天赋{}".format(self.name,self.gift)
            
        def __str__(self):
            return self.cat_info()
    
        
    tom = Cat("汤姆")
    # 方法一
    print(tom)
    # 方法二
    res = str(tom)
    print(res)
    
    # ### __repr__ 魔术方法
    '''
        触发时机: 使用repr(对象)的时候触发
        功能:     查看对象,与魔术方法__str__相似
        参数:     一个self接受当前对象
        返回值:   必须返回字符串类型
    '''
    class Mouse():
        gift = "偷油吃,下不来"
        def __init__(self,name):
            self.name = name
            
        def mouse_info(self):
            return "小老鼠名字{},天赋{}".format(self.name,self.gift)
            
        def __repr__(self):
            return self.mouse_info()
            
        # 在系统底层默认加了如下一句话
        # __str__ = __repr__
    
    jerry = Mouse("杰瑞")
    res = repr(jerry)
    print(res)
    
    print(jerry)
    res = str(jerry)    
    print(res)
        
    __str__魔术方法 示例代码
    # ### __bool__ 魔术方法
    '''
        触发时机:使用bool(对象)的时候自动触发
        功能:强转对象
        参数:一个self接受当前对象
        返回值:必须是布尔类型
    '''
    class MyClass():
        def __bool__(self):
            return False
    
    obj = MyClass()
    res = bool(obj)
    print(res)
    
    #__add__ 魔术方法  (与之相关的__radd__ 反向加法)
    '''
        触发时机:使用对象进行运算相加的时候自动触发
        功能:对象运算
        参数:二个对象参数
        返回值:运算后的值
    '''
    
    class MyClass():
        def __init__(self,num):
            self.num = num
        
        """对象在 加号+ 的左侧时,自动触发"""
        def __add__(self,other):
            print("add方法被触发")
            """
            self 接受的是obj对象
            other 接受的是数字
            """
            # print(self)
            # print(other)
            return self.num + other
        
        """对象在 加号+ 的右侧时,自动触发"""
        def __radd__(self,other):
            """
            self 接受的是对象b
            other 接受的是3
            """
            return self.num + other * 3 # 5 + 3 * 3 = 14
    
    # (1) add 方法
    a = MyClass(10)
    res = a + 1
    print(res)
    
    # (2) radd方法
    b = MyClass(5)
    res = 3 + b
    print(res)
    
    # (3) 对象 + 对象
    """
    先触发add方法
    self  接受a
    other 接受b
    return self.num + other => return 10 + b
    res = 10 + b
    
    后触发radd方法
    self  接受b
    other 接受10
    return self.num + other * 3 => 5 + 10 *3 = 35
    """
    res = a+b
    print(res)
    
    
    #__len__ 魔术方法
    '''
        触发时机:使用len(对象)的时候自动触发 
        功能:用于检测对象中或者类中成员个数
        参数:一个self接受当前对象
        返回值:必须返回整型
    '''
    class MyClass():
        pty1 = 1
        pty2 = 2
        __pty3 = 3
    
        def func1():
            print(1)
        def func2():
            pass
        def __func3():
            pass
            
        def __len__(self):
            dic = MyClass.__dict__
            print(dic)
            """
            {
            '__module__': '__main__', 
            'pty1': 1, 'pty2': 2, '_MyClass__pty3': 3, 
            'func1': <function MyClass.func1 at 0x7f99d664f6a8>, 
            'func2': <function MyClass.func2 at 0x7f99d664f730>, 
            '_MyClass__func3': <function MyClass.__func3 at 0x7f99d664f7b8>, 
            '__len__': <function MyClass.__len__ at 0x7f99d664f840>, 
            '__dict__': <attribute '__dict__' of 'MyClass' objects>, 
            '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, 
            '__doc__': None
            }
            """
            # 方法一
            """
            lst = []
            for i in dic:
                if not( i.startswith("__") and i.endswith("__") ):
                    lst.append(i)
            print(lst)
            """
            # 方法二
            lst = [ i for i in dic if not( i.startswith("__") and i.endswith("__") )]        
            return len(lst)
            
    
    obj = MyClass()
    res = len(obj)
    print(res)
    __bool / add / len 魔术方法 __ 示例代码

    day19

  • 相关阅读:
    window打开服务的dos命令
    struts(三) ---OGNL的学习和理解
    struts(二) ---中参数传值
    struts入门初步(一)
    javaSE之Object及hashcode等相关知识
    CSS小三角制作
    VM安装mac及dmg文件转换iso
    单例模式的学习与简单应用
    Tortoise 下修改服务器路径(Relocate与Switch)
    连接未关闭。 连接的当前状态为打开。问题的解决
  • 原文地址:https://www.cnblogs.com/reachos/p/12177422.html
Copyright © 2011-2022 走看看