• 1.__new__ 魔术方法 单态(例)模式 __del__ 魔术方法(析构方法) __call__ 魔术方法


    一 .__new__ 魔术方法

    '''
        触发时机:实例化类生成对象的时候触发(触发时机在__init__之前)
        功能:控制对象的创建过程
        参数:至少一个cls接受当前的类,其他根据情况决定
        返回值:通常返回对象或None
    '''

    1.基本使用

    class OtherClass():
        pty = 200
    obj2 = OtherClass()
    
    class MyClass():
        pty = 1
        def __new__(cls):
            print('__new__方法被触发')
            print('cls')
            print('<=========>')
            # 返回本类对象 (借父生子)
            # 类.方法(cls)
            # return object.__new__(cls)
            # 不返回对象
            # return None
            # 返回其他类对象   
                return obj2
    
    obj = MyClass()
    print(obj)
    print(obj.pty)
    View Code

     2.__new__ 和 __init__ 的触发时机

    """
    __new__是在造对象时触发
    __init__有对象之后,初始化对象的时候自动触发
    现有对象,在初始化
    """
    class MyClass():
    
        def __new__(cls):
            print(111)
            return object.__new__(cls)
        def __init__(self):
            print(222)
            
    # 实例化对象
    obj = MyClass()

    3.__new__ 和 __init__ 参数需要一一对应

    class MyClass():
    
        def __new__(cls,name):
            print(333)
            return object.__new__(cls)
        def __init__(self,name):
            print(444)
            self.name = name
            
    obj = MyClass("李琦")
    print(obj.name)
    
    # 在__new__中加上收集参数,以不变应万变
    class MyClass():
        
        def __new__(cls,*args,**kwargs):
            print(333)
            return object.__new__(cls)
        def __init__(self,name,sex,age):
            print(444)
            self.name = name
            self.sex = sex
            self.age = age
    obj = MyClass("朱培峰","女性","100")
    print(obj.name)
    print(obj.sex)
    print(obj.age)
    View Code

    4.注意点

    """
    如果没有创建对象,不会触发构造方法
    如果返回的不是本类对象,不会触发构造方法
    """
    class MyClass():
        def __new__(cls):
            print("__new__方法被触发 ... ")
            # return None
            return obj2
            
        def __init__(self):
            print("构造方法被触发 ... ")
    
    obj = MyClass()
    print(obj)

    二 单态模式

     同一个类,无论实例化多少次,都有且只有一个对象;
    """
    作用: 可以减少内存空间的浪费,提升代码执行效率
    场景:如果不需要在创建对象时,在类外额外为当前添加成员,就可以使用单态模式
    """

    (1) 基本使用

    class SingleTon():
        # 类中私有成员属性
        __obj = None
        def __new__(cls):
            print(cls)
            # 类.私有成员属性
            if cls.__obj is None:
                # 存储创建的对象在私有成员__obj当中
                # 类.私有成员属性 = 值(对象)
                cls.__obj = object.__new__(cls)
            #返回该对象
            return cls.__obj
    
    obj1 = SingleTon()
    obj2 = SingleTon()
    obj3 = SingleTon()
    print(obj1)
    print(obj2)
    print(obj3)
    View Code

    (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)
    
    print(obj1,obj2)
    print(obj1 is obj2)
    
    
    
    
    
    
    
    
    """
    # 代码解析:
        第一次,创建一个对象 obj1  赋值name数据为王永娟 self.name = 王永娟  print(obj1.name ) 王永娟
        第二次,创建一个对象 obj2  赋值name数据为荷叶   self.name = 荷叶    print(obj2.name )  荷叶
    
        因为print是一起打印的;
        name = "王永娟"
        name = "荷叶"
        print(name)
        所以打印后者;
    """
        

    三 __del__ 魔术方法(析构方法)

    '''
        触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.所有对象被del的时候]
        功能:对象使用完毕后资源回收
        参数:一个self接受对象
        返回值:无
    '''

    1.基本使用

    class LangDog():
        # 构造方法
        def __init__(self,name):
            self.name = name
                
        # 析构方法
        def __del__(self):
            print("析构方法被触发 ... ")
    
    # 1.页面执行完毕回收所有变量,自动触发
    obj1 = LangDog("小白土狗")
    print(obj1.name)

    2.模拟文件操作

    import os
    class ReadFile():
            
        def __new__(cls,filename):
            # 判断文件是否存在,在创建对象
            if os.path.exists(filename):
                return object.__new__(cls)
            else:
                print("抱歉,该文件不存在")
    
        def __init__(self,filename):
            # 打开文件
            self.fp = open(filename,mode="r",encoding="utf-8")
            
        def readfile(self):
            # 读取文件
            data = self.fp.read()
            return data
            
        def __del__(self):
            # 关闭文件
            self.fp.close()
    
    obj = ReadFile("ceshi1.txt")
    # obj = ReadFile("ceshi1.txt234242234423") 文件不存在,不会创建对象
    res = obj.readfile()
    print(res)
    View Code

    四 __call__ 魔术方法

    '''
        触发时机:把对象当作函数调用的时候自动触发
        功能: 模拟函数化操作
        参数: 参数不固定,至少一个self参数
        返回值: 看需求
    '''

    (1) 基本用法

    class MyClass():
        def __call__(self):
            print("__call__ 方法被触发 ... ")
            
    obj = MyClass()
    obj()

    (2) 模拟洗衣服的过程

    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()
    
    # 方法二
    res = obj("洗衣服")
    print(res)

    3.模拟int操作

    import math
    class MyInt():
        def __call__(self,num):
            
            # 判断是否是布尔类型,做转换
            if isinstance(num,bool):
                if num == True:
                    return 1
                else:
                    return 0
                    
            # 判断是否是整型,做转换
            elif isinstance(num,int):
                return num
                
            # 判断是否是浮点型,做转换
            elif isinstance(num,float):
                # 方法一
                """
                a,b = str(num).split(".")
                return eval(a)
                """
                
                # 方法二
                """ceil  floor"""
                """
                if num >= 0:
                    return math.floor(num)
                else:
                    return math.ceil(num)
                """
                    
                # 简写
                return math.floor(num) if num >= 0 else math.ceil(num)
                
            # 判断是否是字符串
            elif isinstance(num,str):
                # 获取第一为是+或者-,后面全是纯数字,可以转换
                if (num[0] == "+" or num[0] == "-") and num[1:].isdecimal():
                    # 判定符号
                    if num[0] == "+":
                        sign = 1
                    else:
                        sign = -1
                    # 计算数据
                    return self.calc(num[1:],sign)
                    
                elif num.isdecimal():
                    return self.calc(num)
                    
                else:
                    return "抱歉,这个算不了"
                
        def calc(self,num,sign=1):
            # print("<========================>")
            res = num.lstrip("0")
            if res == "":
                return 0
            return eval(res) * sign
            
            
    # int 整型 浮点型 布尔型 纯数字字符串
    myint = MyInt()
    # 布尔型
    res = myint(False)
    print(res)
    # 整型
    res = myint(199)
    print(res)
    # 浮点型
    res = myint(5.77)
    res = myint(-5.77)
    print(res , type(res))
    
    # 字符串
    # res = myint("-00001111")
    
    res = myint("asdfasdf") # -1111 ("-000000000000000000000000")
    print("<============start============>")
    print(res)
    print("<============end============>")
    View Code

     五 __str__ 和 __repr__

    1.__str

    '
    触发时机: 使用print(对象)或者str(对象)的时候触发
    功能: 查看对象
    参数: 一个self接受当前对象
    返回值: 必须返回字符串类型
    '
    class Cat():
        gift = '小猫咪会卖萌,小猫咪抓老鼠'
        def __init__(self,name):
            self.name = name
    
    
        def __str__(self):
            return self.cat_info()
    
    
        def cat_info(self):
            return '小猫咪的名字是{}'.format(self.name)
    
    
    tom = Cat('汤姆')
    res = str(tom)
    print(res)

    手动添加__repr__ = __str__ 把 str 赋值给 str 可以使用 repr()

    2.__repr__

    "
    触发时机: 使用repr(对象)的时候触发
    功能: 查看对象,与魔术方法__str__相似
    参数: 一个self接受当前对象
    返回值: 必须返回字符串类型
    "
    class Mouse():
        gift = "偷粮食"
        def __init__(self,name):
            self.name = name
            
        def __repr__(self):
            return self.mouse_info()
            
        def mouse_info(self):
            return "名字是{},龙生龙,凤生凤,老鼠的儿子会打洞,还会{}".format(self.name,self.gift)
        
        # 系统在底层,自动加了一句赋值操作
        __str__ = __repr__
            
    jerry = Mouse("杰瑞")
    res = repr(jerry)
    print(res)
    
    # 因为系统底层赋值的原因,在打印对象或者强转对象为字符串的时候,仍然可以触发;
    print(jerry)
    res = str(jerry)
    print(res)

    六 __bool__魔术方法

    """
    触发时机: 使用bool(对象)的时候自动触发
    功能: 强制对象
    参数: 一个self接受当前对象
    返回值: 必须是布尔类型
    
    """
    class MyClass():
        def __bool__(self):
            return False
        
    obj = MyClass()
    res = bool(obj)
    print(res)

    七 __add__魔术方法(与之相关的__redd__反向加法)

    """
    触发时机: 使用对象进行运算相加的时候自动触发
    功能: 对象运算
    参数: 二个对象参数
    返回值: 运算后的值
    """
    class MyClass1():
        def __init__(self,num):
            self.num = num
            
        # 对象在加号+的左侧时,自动触发
        def __add__(self,other):
            # print(self)
            # print(other)
            return self.num + other # return 10 + 7 = 17
            
        # 对象在加号+的右侧时,自动触发
        def __radd__(self,other):
            # print(self)
            # print(other)
            return self.num * 2 + other
    
    # 第一种
    a = MyClass1(10)
    res = a + 7 
    print(res) 
    
    # 第二种
    b = MyClass1(5)
    res = 20 + b
    print(res)
    
    # 第三种
    print("<============>")
    res = a+b
    print(res)
    """
    第一次触发魔术方法, a+ =>触发__add__方法
    self => a other => b
    self.num + other => a.num+ b => 10 + b
    
    res = 10 + b
    第二次触发魔术方法 __radd__
    self => b other=> 10
    self.num * 2 + other => b.num*2 + other => 5 * 2 + 10 => 20
    res = 20 
    """

    八 __len__魔术方法

    """
    触发时机: 使用len(对象)的时候自动触发
    功能: 用于检测对象中或者类中成员的个数
    参数: 一个self接受当前对象
    返回值: 必须返回整数
    """
    # len(obj) => 返回类中自定义成员的个数
    class MyClass():
        pty1 = 1
        pty2 = 2
        __pty3 = 3
        pyt3  =10
        pty100 = 90
        
        def func1():
            pass
            
        def __func2():
            pass
            
        def __func3():
            pass
        
        def __len__(self):
            lst = []
            dic = MyClass.__dict__
            # 方法一
            """
            # print(MyClass.__dict__)
            # print(object.__dict__)
            dic = MyClass.__dict__
            for i in dic:
                if not(i.startswith("__") and i.endswith("__")):
                    lst.append(i)
                    
            return len(lst)
            """
            # 方法二
            lst = [i for i in dic if  not(i.startswith("__") and i.endswith("__"))]
            return len(lst)
            
        
    obj = MyClass()
    print(len(obj))
    """
    {
    '__module__': '__main__', 
    'pty1': 1, 
    'pty2': 2, 
    '_MyClass__pty3': 3, 
    'func1': <function MyClass.func1 at 0x7fc198171378>, 
    'func2': <function MyClass.func2 at 0x7fc198171400>, 
    '_MyClass__func3': <function MyClass.__func3 at 0x7fc198171488>, 
    '__len__': <function MyClass.__len__ at 0x7fc198171510>, 
    '__dict__': <attribute '__dict__' of 'MyClass' objects>, 
    '__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
    '__doc__': None
    }
    """

    九 与类相关的魔术属性

    class Man():
        pass
        
    class Woman():
        pass
        
    class Children(Man,Woman):
    
        """
        功能: 描述小孩天生的属性
        成员属性:eye , skin
        成员方法:skylight , moonread , __makebaby    
        """
    
        eye = "万花筒血轮眼"
        skin = "白色"
        
        def skylight(self):
            print("宇智波家族的小孩,天生能够发动天照技能")
            
        def moonread(self,func):
            # func = func111
            print("宇智波家族的小孩,能够发动月亮的光照消灭你~")
            res = func.__name__
            print(res,type(res))
        
        def __makebaby(self):
            print("这一手招数,只能我自己用")

    1.__dict__ 获取对象或类的内部成员结构

    obj = Children()
    print(obj.__dict__)
    print(Children.__dict__)
    View Code

    2.__doc__ 获取对象或类的内部文档

    print(obj.__doc__)
    print(Children.__doc__)
    View Code

    3.__name__ 获取类名函数名

    def func111():    
        print("我是func111方法")
    # 获取函数名
    obj.moonread(func111)
    # 获取类名
    obj.moonread(Man)
    View Code

    4.__class__ 获取当前对象所属的类

    print(obj.__class__)
    View Code

    5.__bases__ 获取一个类直接继承的所有父类,返回元组

    print(Children.__bases__)
    View Code
  • 相关阅读:
    为 HTTP/2 头压缩专门设计的 HPACK
    HTTP2 帧基础知识以及Header、CONTINUATION、DATA帧相关资料:
    扩充巴科斯-瑙尔范式 ABNF简介
    我Win下常用工具清单
    gRPC版本的 Google APIs
    gRPC 的route_guide例子
    proto3 笔记1
    编译gRPC Go版本使用的 ProtoBuffer 文件
    新浪校园招聘2013.10.30浙大玉泉4教301笔试的前端妹纸,像雾像雨又像风
    Android下Notification,样式style,主题theme的功能实现
  • 原文地址:https://www.cnblogs.com/whc6/p/14150856.html
Copyright © 2020-2023  润新知