zoukankan      html  css  js  c++  java
  • Python3.x基础学习-类--__del__()、__call__()、__repr__()、__new__()、__hash__()方法

    __del__()

    销毁魔术方法
    触发时机:当一个对象在内存中被销毁的时候自动执行
    参数:至少有一个 self,
    接收对象 返回值:无
    作用:在对象销毁的时候做一些操作
    注意:程序自动调用此方法,不需要我们手动调用。

    class Cat:
        def __init__(self,name):
            print("--init--")
            self.name = name
    
        def __str__(self):
            print("--str--")
            return self.name
    
        def __del__(self):
            print("这是del方法")  #对象一旦被销毁,自动触发此方法
    
    cat1 = Cat("Tom")
    print(cat1)
    print("最后一行代码")
    # --init--
    # --str--
    # Tom
    # 最后一行代码
    # 这是del方法
    class Cat:
        def __del__(self):
            print('----del-----')
    
    def func():
        cat = Cat()
        return cat   #即使有返回值,但函数外部没有变量接受,出了函数对象依然会被销毁
    ret =func()
    print("最后一行代码")
    
    # 最后一行代码
    # ----del-----

    __call__()

    方法__call__():可以让类的实例具有类似于函数的行为,进一步模糊了函数和对象之间的概念
    使用方式:对象后面加括号,触发执行。即:对象()或者 类()()
    class Cat:
        def eat(self):
            print("吃猫粮")
        def __call__(self, *args, **kwargs):
            print("--call方法--")
    
    cat = Cat()
    cat.eat()
    cat()
    Cat()()
    
    # 吃猫粮
    # --call方法--
    # --call方法--
    
    #__call__方法实现斐波那契  1,1,2,3,5,添加到列表中
    
    class Fib:
        def __call__(self, n):
            self.list = []
            a = 1
            b = 1
            for i in range(1,n+1):
                self.list.append(a)
                a,b = b,a+b
            return self.list
    
    fib =Fib()
    print(fib(5))
    
    
    def fib1(n):
        x=[]
        if n==1 or n==2:
            return 1
        return fib1(n-2)+fib1(n-1)
    
    print(fib1(5))
    print(fib1(4))
    
    # [1, 1, 2, 3, 5]
    # 5
    # 3

    __repr__()

    __repr__():改变对象的字符串显示
    -此方法是 __str__()的备胎,如果找不到__str__()就会找__repr__()方法。
    -%r默认调用的是__repr()方法,如果是字符串会默认加上''
    -repr()方法默认调用__repr__()方法
    class Person:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def __str__(self):
            return str(self.__dict__)
    
        def __repr__(self):
            return 'name:%s--age:%d'%(self.name,self.age)
    
    
    per = Person('johnson',18)
    print(per)
    
    string ='zhou'
    print("大家好,我叫%s"%string)
    print("大家好,我叫%r"%string)
    
    # %s 默认调用str方法,%r默认调用repr方法
    print("大家好,我叫%r"%per)
    print("大家好,我叫%s"%per)
    
    # {'name': 'johnson', 'age': 18}
    # 大家好,我叫zhou
    # 大家好,我叫'zhou'
    # 大家好,我叫name:johnson--age:18
    # 大家好,我叫{'name': 'johnson', 'age': 18}

    __new__()方法

    触发机制:在实例化对时触发
    参数:至少一个cls接收当前类
    返回值:必须返回一个对象实例 作用:实例化对象
    注意:实例化对象 Object 类底层实现,其他类继承了Object的__new__才能够实例化对象
    没事别碰这个魔术方法,先触发__new__()才触发__init__
    class Cat:
        def __init__(self):
            print('--init--')
        def __new__(cls, *args, **kwargs):
            print('---new---')
            return object.__new__(cls)  #成功创建了对象,但一出函数对象就被销毁
        def __del__(self):
            print('--del--')
    
        def __str__(self):
            return '--str--'
    
    def func():
        cat = Cat()
        print(cat)
        return cat
    
    ret = func()
    print('最后一行代码------')
    
    # ---new---
    # --init--
    # --str--
    # 最后一行代码------
    # --del--
    class Shopping:
        __instance = None
    
        def __new__(cls, *args, **kwargs):
            if cls.__instance==None:
                cls.__instance = object.__new__(cls)
                return cls.__instance
            else:
                return cls.__instance
    
    shop1 = Shopping()
    shop2 = Shopping()
    print(id(shop1),id(shop2))
    print(shop1,shop2)
    shop3 = Shopping()
    print(id(shop3))
    
    # 1395248497888 1395248497888
    # <__main__.Shopping object at 0x00000144DB4A84E0> <__main__.Shopping object at 0x00000144DB4A84E0>
    # 1395248497888

     __hash__()

    哈希(hash)也翻译叫散列。hash算法,是将一个不定长的输入,通过hash函数变换成一个定长的输出,即哈希值
    在python中,有内置的哈希函数hash(),返回一个对象(数字、字符串,不能直接用于list,set,dict)的哈希值
    set1 ={1,2,3}
    dic = {'a':1}
    # print({[1]:1}) # TypeError: unhashable type: 'list'
    
    string = 'a'
    print(hash(string))
    print(hash((1,3)))
    # 8878686175204649982
    # 3713081631933328131
    1.自定义对象能不能添加到集合中呢?  能默认调用父类的__hash__和 __eq__
    2.object的hash值是怎么算的呢? id是hash的16倍
    3.自定义对象添加到集合中,一般认为两个对象的属性值相同就是同一个对象 --自定义计算规则
    4.注意:如果只定义了__eq__方法,没有定义__hash__方法,__hash__方法会隐式设置成None
    class Person:
        def __init__(self,num):
            self.num = num
    
    p1 =Person(1)
    p2 =Person(2)
    p3 =Person(3)
    list =[p1,p2,p3]
    set(list)
    print(id(p1))
    print(hash(p1))
    
    # 2424376266626597764
    # 3713081631933328131
    # 2187348381144
    # -9223371900145501987
    class Person:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __eq__(self,other):
            print("%s调用了eq方法"%self.name,self.age)
            return self.__dict__==other.__dict__
        def __hash__(self):
            print("%s调用了hash方法"%self.name)
            return hash(self.name)
    p1 = Person('johnson',18)
    p2 = Person("may",11)
    p3 = Person('johnson',18)
    print(id(p1),id(p2),id(p3))
    set1 = {p1,p2,p3}
    print(p1==p3)
    
    # 2744803718088 2744803718032 2744803717976
    # johnson调用了hash方法
    # may调用了hash方法
    # johnson调用了hash方法
    # johnson调用了eq方法 18
    # johnson调用了eq方法 18
    # True
    https://www.cnblogs.com/kadycui/p/11838590.html
    Python的__hash__函数和__eq__函数
    可哈希的集合(hashed collections),需要集合的元素实现了__eq__和__hash__,而这两个方法可以作一个形象的比喻:
    哈希集合就是很多个桶,但每个桶里面只能放一个球。
    __hash__函数的作用就是找到桶的位置,到底是几号桶。
    __eq__函数的作用就是当桶里面已经有一个球了,但又来了一个球,它声称它也应该装进这个桶里面(__hash__函数给它说了桶的位置),双方僵持不下,那就得用__eq__函数来判断这两个球是不是相等的(equal),如果是判断是相等的,那么后来那个球就不应该放进桶里,哈希集合维持现状。
    class Foo:
        def __init__(self, item):
            self.item = item
    
        def __eq__(self, other):
            print('使用了equal函数的对象的id',id(self))
            if isinstance(other, self.__class__):
                return self.__dict__ == other.__dict__
            else:
                return False
        def __hash__(self):
            print('f'+str(self.item)+'使用了hash函数')
            return hash(self.item)
    f1 = Foo(1)
    f2 = Foo(2)
    f3 = Foo(3)
    fset = set([f1, f2, f3])
    print(fset)
    print()
    f = Foo(3)
    fset.add(f)
    print('f3的id:',id(f3))
    print('f的id:',id(f))
    
    # f1使用了hash函数
    # f2使用了hash函数
    # f3使用了hash函数
    # {<__main__.Foo object at 0x00000245E50AA518>, <__main__.Foo object at 0x00000245E52484A8>, <__main__.Foo object at 0x00000245E5248470>}
    # 
    # f3使用了hash函数
    # 使用了equal函数的对象的id 2499220374640
    # f3的id: 2499220374640
    # f的id: 2499220376992
  • 相关阅读:
    解决VTune错误.../lib64/libstdc++.so.6: version `GLIBCXX_3.4.14&#39; not found (required by ...)
    【环境配置】配置sdk
    Eclipse设置Android Logcat输出字体大小
    Vertica数据库操作
    hihoCoder#1038 : 01背包
    初识Dubbo 系列之4-Dubbo 依赖
    计算机相关专业的同学该怎么用自己的计算机
    十天学习PHP之第三天
    Android之Fragment的优点和作用
    Fragment的生命周期
  • 原文地址:https://www.cnblogs.com/johnsonbug/p/12708548.html
Copyright © 2011-2022 走看看