zoukankan      html  css  js  c++  java
  • 4.魔术方法1-init-new-del-call

    魔术方法 init, new, del ,call

    1. init 构造方法

    # __init__ 魔术方法(构造方法)
    """
    魔术方法:
          系统自动调用的方法,按照触发机制调用
    """
    # __init__ : 构造方法
    """
    触发机制 : 实例化对象,初始化时触发
    功能 :  为对象添加成员
    参数 : 至少一个self参数
    返回值: 无
    """
    # 1.基本使用
    class Class():
        def __init__(self):
            print("构造方法被触发")
            self.name="熊大"
    
    obj = Class() #实例化对象,init被触发
    print(obj.__dict__) #查看obj对象成员 {'name': '熊大'}
    print(obj.name) #熊大
    
    # 2.带有参数的构造方法
    """
    在实例化对象时,给予构造方法参数
    """
    # 传入一个参数
    class Class():
        def __init__(self,name):
            self.name=name
    obj = Class("贾英贺") #实例化传参
    print(obj.__dict__) #{'name': '贾英贺'}
    print(obj.name) #贾英贺
    
    # 传入多个参数
    class People():
        def __init__(self,name,skin):
            self.name=name
            self.skin=skin
        def info(self):
            print("姓名:{},肤色:{}".format(self.name,self.skin))
    
    obj = People("舒畅","黄色")
    print(obj.__dict__) #{'name': '舒畅', 'skin': '黄色'}
    obj.info() #姓名:舒畅,肤色:黄色
    

    2. new 魔术方法

    # __new__魔术方法
    """
    触发时机 : 实例化类生成对象的时候触发(触发时机在__init__构造方法之前)
    功能: 控制对象的创建过程
    参数 : 至少一个cls接收当前的类(cls是本类),其他根据情况决定
    返回值 : 通常返回对象或None
    """
    
    # 1.基本使用
    """
    return 返回啥,obj就是啥
    """
    class Class():
        pty=1
        def __new__(cls):
            print("new被触发")
    obj = Class()
    print(obj) # 没有返回值obj就是None
    
    class Class():
        pty=1
        def __new__(cls):
            print("new被触发")
            return 22
    obj = Class()
    print(obj) # 22 返回什么就是什么
    
    class Class():
        pty=1
        def __new__(cls):
            print("new被触发")
            return object.__new__(cls)
    obj = Class()
    print(obj) # 借助父类产生本类对象
    print(obj.pty) #1
    
    class M():
        pty=111
    obj1 = M()
    
    class Class():
        pty=1
        def __new__(cls):
            print("new被触发")
            return obj1
    obj = Class()
    print(obj) # 还可以返回其他类对象
    print(obj.pty) #111
    
    # 2.__new__和__init__的触发时机
    """
    __new__ 是在创造对象时触发
    __init__ 是在有本类对象后,初始化本类对象的时触发
    先有对象,才能初始化对象
    """
    class Me():
        def __init__(self):
            print("init被触发")
        def __new__(cls):
            print("new被触发")
            return object.__new__(cls)
    obj = Me() #new触发后,init才被触发
    
    # 3.__new__和__init__的参数需要一一对应 否则报错
    class My():
        def __new__(cls,name):
            return object.__new__(cls)
        def __init__(self,name):
            self.name=name
    obj = My("光头强")
    print(obj.name) #光头强
    
    # 解决办法 : 可以在__new__中加上收集参数,以不变应万变
    class A():
        def __new__(cls,*args,**kwargs)
            return object.__new__(cls)
        def __init__(self,name,sex):
            self.name=name
            self.sex=sex
    obj = A("小强","男")
    print(obj.name)
    print(obj.sex)
    
    2.1 单态模式
    # 单态模式:同一个类,无论实例化多少次,都有且只有一个对象
    """
    作用 : 可以减少内存空间的浪费,提升代码执行效率
    应用场景: 如果不需要在创建对象时,在类外为当前对象添加成员,就可以使用单态模式
    """
    class Me():
        __obj=None
        def __new__(cls):
            if cls.__obj is None: #关键字最好用is判断,虽==也可以
                cls.__obj = object.__new__(cls)
                # 使用类调用属性更改了成员属性
            return cls.__obj
    
    obj1=Me()
    obj2=Me()
    print(obj1) #<__main__.Me object at 0x7f8153681470>
    print(obj2) #<__main__.Me object at 0x7f8153681470>
    """无论实例化多少次,内存地址是一样的,都是第一个实例化对象地址"""
    
    # 注意点
    class Me():
        __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=Me("光头强")
    obj2=Me("熊大")
    print(obj1.name) #熊大
    print(obj2.name) #熊大   
    print(obj1.__dict__) #{'name': '熊大'} 查看对象中成员
    print(obj2.__dict__) #{'name': '熊大'}
    """
    obj1和obj2地址一样,指向是一个对象,
    对象中成员self.name 第二次赋值把第一次覆盖了
    所以打印的是最后一次赋值结果
    """   
    

    3. del 析构方法

    # __del__魔术方法(析构方法)
    """
    触发时机: 当对象被内存回收的使用自动触发
        1.页面执行完毕自动回收所有变量
        2.所有对象都被del删除的时候
    功能: 对象使用完毕后资源回收
    参数: 一个self 接收参数
    返回值: 无
    """
    # 1.基本使用
    class J():
        def __init__(self,name): #构造方法
            self.name=name
        def __del__(self): #析构方法
            print("析构方法被触发")
    
    # 1.页面执行完毕自动回收所有变量
    obj=J("光头强") #析构方法被触发
    
    # 2.所有的对象都被del删除的时候
    """
    注意: 当一个数据没有被任何变量引用的时候,才会真正的被内存释放掉
    """
    obj1=obj
    print("--------")
    del obj
    del obj1 #析构方法被触发
    print("--------")
    
    # 2.模拟文件操作
    import os
    class ReadFile():
        def __new__(cls,filename):
            if os.path.exists(filename): #判断文件是否存在 用isfile也可以
                return object.__new__(cls)
            else:
                print("文件不存在")
        def __init__(self,filename):
            self.fp=open(filename,mode="r",encoding="utf-8") #打开文件
        def read(self):
            return self.fp.read() #读取文件
        def __del__(self):
            self.fp.close() #关闭文件
    
    obj = ReadFile("lianxi.txt")
    print(obj.read())  #读取文件
    

    4. call 魔术方法

    # __call__魔术方法
    """
    触发时机: 把对象当成函数调用的时候自动触发
    功能: 模拟函数化操作
    参数: 参数不固定,至少一个self参数
    返回值: 看需求
    """
    # 1.基本用法
    class Me():
        def __call__(self):
            print("call 被触发")
    obj = Me()
    obj()
    
    # 2.模拟洗衣过程
    class Wash():
        def step1(self):
            print("衣服扔进洗衣机")
        def step2(self):
            print("加洗衣液")
        def step3(self):
            print("晾干")
        def __call__(self,something):
            print(something)
            self.step1()
            self.step2()
            self.step3()
            return "洗完了"
    
    obj = Wash()
    res = obj("洗衣服")
    print(res)
    
    # 3.模拟int强转操作
    import math
    class Int():
        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)
                """
                # 方法二: 利用math模块,向上向下取整
                """
                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 == "": #是否为空字符串
                    return "这个算不了"
                else:
                    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):
            res = num.lstrip("0")
            if res == "":
                return 0
            return eval(res) * sign
    
    obj = Int()
    res = obj("") #这个算不了
    print(res)
    res = obj("000221") #221
    print(res)
    
  • 相关阅读:
    LeetCode——Reverse Integer
    多校第一场 费马小定理+模拟+组合数学
    Oracle 物理和逻辑备库健康监測的一个根据
    UFLDL教程笔记及练习答案三(Softmax回归与自我学习***)
    MAC上Nuclide的安装
    free命令具体解释——Linux性能分析
    不同浏览器对于html5 audio标签和音频格式的兼容性
    如何在 Internet Explorer 11中开启 WebGL
    Cocos2d-html5帧动画
    Cocos开发前准备
  • 原文地址:https://www.cnblogs.com/jia-shu/p/14151800.html
Copyright © 2011-2022 走看看