zoukankan      html  css  js  c++  java
  • del new item hash 单例模式

    一.析构方法__del__和构造方法__new_

    析构方法: 删除一个对象的时候调用的方法
    构造方法: 创建一个对象的
    初始化方法: __init__ 给已经创建出来的对象添加属性初始化方法

    1.析构方法:

    class A:
        def __init__(self,name):
            self.name=name
        def __del__(self):
            print(666)
    a=A("alex")
    del a
    print(a.__dict__)  #NameError: name 'a' is not defined
    View Code
    删除一个对象的时候,如果内部存在__del__方法,那么在删除一个对象之前先执行__del__方法中的代码
    析构函数的调用是由解释器在进行垃圾回收时自动触发执行的
    class Foo:
    def __del__(self):
    print('执行我啦')
    f1=Foo() #执行我啦
    ##没有删-除对象,却仍然执行了__del__函数。原因是解释器在代码全部执行完后会收集没执行的代码,因此会触发
    这个函数执行

     

    2.__new__创造一个对象。即实例化时为什么能实例化出来一个对象

    
    
    class A:
        def __init__(self):
            print("执行了init方法")
        def __new__(cls, *args, **kwargs):
            print("执行了new方法")
            return object.__new__(cls)
    a=A()
    # 执行了new方法 执行了init方法
    print(type(a))  #<class '__main__.A'>
    print(type(A)) #<class 'type'>
    View Code
    
    
    实例化的实质:先执行__new__方法 创造出一个对象 然后把创造出来的对象传递给__init__方法

    二.元类和单例模式

    1.元类:type()

    类和对象都不是凭空出此现的。对象的产生是类创造的。也有一个类在创建类,这个类叫做元类
    type() 所有直接用class创建出来的类的元类都是type
    class Preson:pass
    print(type(Preson)) #<class 'type'>
    class Preson:pass 的完整形式是class Preson(metaclass=type):pass
    在接口类和抽象类中不能实例化的原因就是改变了元类
    元类 创造 类 所以所有的类的type都是它的元类,默认是type
    类 创造 对象 具体创造对象的方法 __new__方法,所有的对象的type都是它对应的类

    2.单例模式:一个类可以被多次实例化 但是同一时间在python的内存中,只能有一个实例

    class A:
        def __init__(self,name):
            self.name=name
            #print("执行了init")
        def __new__(cls, *args, **kwargs):
            #print("执行了__new__")
            if not hasattr(A,'instance'):
                A.instance=object.__new__(cls)  #instance为A的静态变量
            return A.instance
    a=A("alex")
    print(a.name)  #alex
    b=A("egon")
    print(a.name,b.name) #egon egon
    View Code

    三.item系列

    1.__item__系列 操作a['name']这种形式

    __getitem__
    class A:
        def __init__(self,name):
            self.name=name
            self.age=18
        def __getitem__(self,item):
           return self.__dict__[item]
    a=A('alex')
    print(a['name'],a['age']) #  alex 18 对应了类中一个方法的语法
    先进行初始化,然后执行__getitem__ 在return时不能return self.[item] 对象并没有[item]这种属性
    View Code

    2.###增加.修改和删除一个属性

    class A:
        def __init__(self,name):
            self.name=name
            self.age=18
        def __getitem__(self, item):
            return self.__dict__[item]
        def __setitem__(self, key, value):
           self.__dict__[key]=value
        def __delitem__(self, key):
            del self.__dict__[key]
    a=A('alex')
    ##增加属性
    a['sex']='nan'
    print(a.__dict__)  #{'name': 'alex', 'age': 18, 'sex': 'nan'}
    ###查看
    print(a.sex)  #nan
    print(a["sex"]) #nan
    ##修改##
    a['sex']='不详'
    print(a.__dict__)  #{'name': 'alex', 'age': 18, 'sex': '不详'
    ##删除##
    del a['sex']
    print(a.__dict__) #{'name': 'alex', 'age': 18}
    View Code

    四.__call__和__hash__

    1.__call__
    class A:
    def __call__(self,a):
    print('执行我了',a)
    a = A()('aaa') #等同于a=A() a('aaa')
    2.__hash__
    不可变的数据类型都可以被hash
    class A:
    def __hash__(self):
    return 1
    a = A()
    b = A()
    print(hash(a))
    print(hash(b))
    hash(obj)函数,obj对象对应的类必然内部实现了__hash__方法
    hash的结果就是__hash__方法的返回值
    且在一次成的执行过程中是不会发生变化的
    且要想作为字典的key或者作为集合的元素,这个对象对应的类必须实现__hash__方法
    
    
    面试题

    
    
    有一个类,对应这个类产生了100个对象
    每个对象有三个属性 : 姓名 年龄 性别
    请对这一百个对象进行去重,如果姓名和性别相同,即便年龄不同也是相同的对象
    '''
    class Person:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
        def __hash__(self):
            return hash('%s%s'%(self.name,self.sex))
        def __eq__(self, other):
            if self.name == other.name and  
                self.sex == other.sex:
                return True
    p_lst = []
    for i in range(100):
        p_lst.append(Person('egon',i,'male'))  #print(Person('egon',18,'male'))显示对象的地址
    print(p_lst)
    print(set(p_lst)) # 报错不可hash 完成了__hash__
    View Code
    
    
    
     
     
     
     
  • 相关阅读:
    ESP8266 在线构建 固件
    NodeMCU 物联网开发快速上手
    vofaplus-plugins dtantdir
    欧拉角
    DebugView 简单使用
    Intrusion Detection Evaluation Dataset (CIC-IDS2017)
    ureport
    how to ignore server cert error in javamail
    465和587区别
    JavaMail 发送邮件阻塞问题解决——设置 smtp 超时时间
  • 原文地址:https://www.cnblogs.com/zgf-666/p/8561426.html
Copyright © 2011-2022 走看看