• python -- 双下方法


    7.8面向对象:双下方法

    定义: 双下方法是特殊方法. 我们在开发中尽量不要使用使用双下方法

    7.8.1 __len__

    class B:
        def __len__(self): # 必须有一个int类型的返回值 否则会报错,但仍会执行此方法
            print(999)
            return 666
    b = B()
    print(len(b))   # len 一个对象就会触发 __len__方法
    
    class A:
        def __init__(self):
            self.name = 'Agoni'
            self.age = 18
    
        def __len__(self):
            return len(self.__dict__)  # 返回的是a 对象的全部内容的长度
    
    a = A()
    print(len(a))
    
    # 一个对象之所以可以使用len()函数,根本原因是这个对象从属于的类中有__len__方法
    

    7.8.2 __hash__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __hash__(self):
            return hash(str(self.a)+str(self.b))
    obj = A()
    print(hash(obj))  # 会调用obj这个对象的类(基类)的__hash__方法
    

    7.8.3 __str__ , __repr__

    如果一个类中定义了__str__或__repr__方法,那么在打印对象时,默认输出该方法的返回值

    class Student:
        def __init__(self,name,age):
            self.name = name
            self.age = age
            
        def __str__(self):  # 优先级要高
            return f'姓名:{self.name},年龄:{self.age}'
        
        def __repr__(self):
            return f'姓名:{self.name},年龄:{self.age}'
            
    obj1 = Student('a',18)
    obj2 = Student('b',18)
    
    print(str(obj1)) # 会触发 __str__
    print(str(obj2)) # 会触发 __repr__
    
    print(obj1)
    print(obj2)  # 打印输出实例会出发__str__ 和 __repr__
    
    print('此对象为%s' % obj1)  # 格式化输出会触发__str__
    print('此对象为%r' % obj2)  # 格式化输出会触发__str__
    

    7.8.4 __call__

    对象后面加括号,触发执行。

    注:构造方法__new__的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

    class A:
        def __init__(self):
            self.a = 1
            print(111)
    
        def __call__(self, *args, **kwargs):
            print(666)
    
    obj = A()
    obj()
    

    7.8.5 __eq__

    对一个类的两个对象进行比较操作,就会触发__eq__方法

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __eq__(self,obj):
            print(111)
            return True
            # if self.a == obj.a and self.b == obj.b:
            #     return True
    a = A()
    b = A()
    print(a == b)
    

    7.8.6 __del__

    析构方法,当对象在内存中被释放时,自动触发执行。

    注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

    class A:
    
        def __del__(self):
            print(111)
    
    obj = A()
    del obj    # 打印111
    l1 = [1,2,3]
    dic = {1:2}
    del l1
    del dic  # 主动删除
    print(dic) # 会报错
    print(111)
    print(222)
    

    7.8.7 __new__***

    __new__ 构造方法: __new__ 创造并返回一个新对象

    class A(object):
    
        def __init__(self):
            print('in __init__')
    
        # 这里的__new__不能创造空间,必须引用父类的__new__创造空间
        def __new__(cls, *args, **kwargs): # 传一个类给cls,确定给哪个类创建空间
            print('in __new__')
            object1 = object.__new__(cls)
            return object1
    obj = A()  # 类名() 先触发__new__ 并且将类名自动传给cls
    print(obj)
    

    单例模式 -- 一种设计模式 (面试手写单例模式)

    一个类只能实例化一个对象,无论你实例化多少次,内存中都只有一个对象

    这个类的对象不是个性化的,主要是实例化对象之后去执行类中的方法

    class A:
        __instance = None
        
        def __new__(cls,*args.**kwargs):
            if not __instance:
                object1 = object.__new__(cls)
                cls.__instance = object1
            return cls.__instance
        
    obj1 = A()
    obj2 = A()
    print(obj1,obj2)  # 两个对象空间相同
    

    7.8.8 __item__

    对 对象类似于字典的操作时使用

    class Foo:
        def __init__(self,name):
            self.name = name
    
        def __getitem__(self, item):
            print(self.__dict__[item])  # 得到Agoni
            print(item)  # name
            print('get时,执行我')
    
        def __setitem__(self, key, value):
            self.__dict__[key] = value # 才是更改 __init__ 的属性name
            print(key,value)   # name 小姐姐
            print('set时,执行我')
        def __delitem__(self, key):
            print(f'del obj{[key]}时,我执行')
            self.__dict__.pop(key)
    
    obj = Foo('Agoni')
    obj['name']  # 将 name 传给 item
    obj['name'] = '小姐姐'  # 将 name 和 小姐姐 传给 key 和 value ,  __init__ 的属性name
    print(obj.name)  # 小姐姐
    del obj['name']
    

    7.8.9 __enter__ __exit__

    class A:
        def __init__(self,name):
            self.name = name
    
        def __enter__(self):
            print('开始')
        def __exit__(self, exc_type, exc_val, exc_tb):
            print('结束')
    
    # 对一个对象类似于进行with语句上下文管理的操作,必须在类中定义__enter__ 和__exit__
    with A('Agoni') as obj:
        print(666)
    print(obj.name)  # 这里会报错(看下面例子,会解决)
    开始
    666
    结束
    
    # 举例
    class A:
        
        def __init__(self, text):
            self.text = text
        
        def __enter__(self):  # 开启上下文管理器对象时触发此方法
            self.text = self.text + '您来啦'来了来了
            return self  # 将实例化的对象返回f1
        
        def __exit__(self, exc_type, exc_val, exc_tb):  # 执行完上下文管理器对象f1时触发此方法
            self.text = self.text + '这就走啦'
            
    with A('大爷') as f1:
        print(f1.text)
    print(f1.text)
    
  • 相关阅读:
    二:虚拟游戏摇杆
    一:AndEngine的小例子
    打造属于自己的安卓Metro界面
    linux设备驱动第四篇:驱动调试方法
    C# 二叉查找树实现
    初识 Angular 体会
    C# 霍夫曼二叉树压缩算法实现
    TypeScript笔记[5]泛型+Dictionary 转
    Axiom3D学习日记 5.Frame Listeners, and Input Handling
    Axiom3D学习日记 4.地形,天空,雾
  • 原文地址:https://www.cnblogs.com/Agoni-7/p/11210291.html
Copyright © 2020-2023  润新知