zoukankan      html  css  js  c++  java
  • python的魔术方法

    一、魔术方法特殊属性

    • __name__ : 类、函数、方法等的名字
    •  __module__: 定义所在的模块名
    •  __class__ : 对象或类所属的类
    •  __bases__ : 类的基类的元组,顺序为它们在基类列表中出现的顺序
    •  __doc__ : 类、函数的文档字符串,如果没有定义则为None
    •  __mro__ :类的mro,class.mro()返回结果的保存在__mro__中
    •  __dict__ : 类或实例的属性,可写的字典

    二、查看属性

    1、__dir__方法:

    • 返回类或者对象的所有成员名称列表,dir()函数就是调用__dir__方法
    • 如果提供__dir__(),则返回属性的列表,否则会尽量从__dict__属性中收集信息

    2、dir()对应不同类型的对象具有不同的行为:

    •  如果对象是模块对象,列表包含模块的属性名
    •  如果对象是类型或类对象,列表包含类的属性名,机它的基类的属性名
    •  否则,列表包含对象的属性名,它的类的属性名和类的基类的属性名

    三、魔术方法的分类

    • 创建与销毁:__init__与__del__
    • hash:__hash__方法:内建函数hash()调用的返回值,返回一个整数,如果定义这个方法该类的实例就可hash
    举例:
        class A:
            def __init__(self):
                self.a = 'a'
                self.b = 'b'
            
            def __hash__(self):
                return 1
            
            def __eq__(self,other):
                return self.a = other.a
    
    print(hash(A()))
    print((A(),A()))
    print({A(),A()})
    s = {A(),A()}  # set集合
    print(s)    
    
    执行输出:
        1
        (<__main__.A object at 0x0000000004E4C780>, <__main__.A object at 0x0000000004E4C860>)
        {<__main__.A object at 0x0000000004E4C6D8>, <__main__.A object at 0x0000000004E4C860>}
        {<__main__.A object at 0x0000000004E4C780>, <__main__.A object at 0x0000000004E4C6D8>}
    
        上例set为什么不能剔除相同的key

    1、__eq__方法:对应==操作符,判断2个对象是否相等,返回值bool

    class A:
        def __init__(self):
            self.a = 'a'
            self.b = 'b'
        
        def __hash__(self):
            return 1
        
        def __eq__(self,other):
            return self.a == other.a
    
    print(hash(A()))
    print((A(),A()))
    print({A(),A()})
    s = {A(),A()}  # set集合
    print(s)
    执行输出:
    1
    (<__main__.A object at 0x0000000004E4C9B0>, <__main__.A object at 0x0000000004E4CB00>)
    {<__main__.A object at 0x0000000004E4CB38>}
    {<__main__.A object at 0x0000000004E4C9B0>}
    
    
    __hash__方法只是返回一个hash值作为set的key,但是去重还需要__eq__来判断2个对象是否相等
    hash值相等,只是hash冲突,不能说明两个对象是相等的,因此,一般来说提供__hash__方法是为了作为set或者dict的key的,所以去重要同时提供__eq__方法
    可hash对象必须提供__hash__方法,没有提供的话,isinstance(p1,collections.Hashable)一定为False


    2、list类为什么不可hash?

    • 源码中有一句__hash__ = None,也就是说如果调用__hash__()相当于None(),一定报错
    • 所有类都继承object,而这个类是具有__hash__()方法的,如果一个类不能被hash,就是把__hash__设置为None了
    from collections import Hashable
    
    class Point:
        def __init__(self,x,y):
            self.x = x
            self.y = y
        
        def __hash__(self):
            return hash((self.x,self.y))
        
        def __eq__(self,other):
            return self.x == other.x and self.y == other.y
    
    p1 = Point(4,5)
    p2 = Point(4,5)
    print(hash(p1))
    print(hash(p2))
    
    print(p1 is p2)
    print(p1 == p2)
    print(set((p1,p2)))
    
    执行输出:
        3713084879518070856
        3713084879518070856
        False
        True
        {<__main__.Point object at 0x0000000004E5C2E8>}

    3、bool方法

    • __bool__方法: 内建函数bool(),或者对象放在逻辑表达式的位置,调用这个函数返回布尔值
    •  没有定义__bool__(),就找__len__()返回长度,非0为真,如果__len__()也没有定义,那么所有实例都返回真
    举例:
        class A:
        pass
    
    print(bool(A()))   #没有定义
    
        class B:
            def __bool__(self): # 定义了返回函数返回值
                return False
    
    print(bool(B))
    print(bool(B()))
    
        class C:
            def __len__(self):  #定义了len
                return 0
    print(bool(C()))


    四、可视化

    • __repr__ : 内建函数repr()对一个对象获取字符串表达,调用__repr__方法返回字符串表达;如果__repr__没有定义,就直接返回object的定义就是显示内存地址信息
    •  __str__ : str()函数,内建函数format,print()函数调用,需要返回对象的字符串表达;如果没有定义,就去调用__repr__方法返回字符串表达,如果__repr__没有定义,就直接返回对象的内存地址信息
    •  __bytes__ : bytes的时候,返回一个对象的bytes表达,即返回bytes对象
    举例:
        class A:
        def __init__(self):
            self.a = 'a'
            self.b = 'b'
        def __repr__(self):
            return 'repr:{},{}'.format(self.a,self.b)
        
        def __str__(self):
            return 'str:{},{}'.format(self.a,self.b)
    
    print(A())  # 优先使用__str__函数
    print([A()]) # []使用__str__,但其内部使用__repr__
    print(([str(A())])) #[]使用__str__,str()函数也是用__str__
    print('str:a,b')
    s = 'b'
    print(['a'],(s,))
    
    执行输出:
    str:a,b
    [repr:a,b]
    ['str:a,b']
    str:a,b
    ['a'] ('b',)


    五、运算符重载

    •  operator模块提供以下的特殊方法,可以将类的实例使用下面的操作符类操作
    •  比较运算符:__lt__,__le__,__eq__,__gt__,__ge__,__ne__
    •  算数运算符、移位:__add__,__sub__,__mul__,
    举例:
        
        class A:
            def __init__(self,x):
                self.x = x
            
            def __sub__(self,other):
                return self.x - other.x
            
            def __isub__(self,other):
                tmp = self.x - other.x
                return A(tmp)
            
            def __str__(self):
                return str(self.x)
    
    x = A(5)
    y = A(4)
    print(x,y)
    print(x-y,x.__sub__(y))
    
    x -= y
    print(x)
    
    
    完成Point类设计,实现判断点相等的方法,并完成向量的加法
    
    class Point:
        def __init__(self,x,y):
            self.x = x
            self.y = y
        
        def add(self,other):
            return Point(other.x + self.x, other.y + self.y)
        
        def __add__(self,other):
            return (self.x + other.x, self.y + other.y)
        
        def __eq__(self,other):
            return self.x == other.x and self.y == other.y
        
        def __str__(self):
            return "Point:{},{}".format(self.x,self.y)
    
    p1 = Point(1,1)
    p2 = Point(2,2)
    points = (p1,p2)
    print(points[0].add(points[1]))
    
    print('=========运算符重载============')
    print(points[0] + points[1])
    print(Point(*(points[0] + points[1])))
    print(p1 == p2)
    
    
    运算符重载应用场景
        往往是用面向对象实现的类,需要做大量的运算符是这样运算在数学上最常见的表达方式
        提供运算符重载,比直接提供加法方法要更加合适该领域内使用者的习惯


     

  • 相关阅读:
    PS 修复画笔
    PS 魔棒工具、仿制图章
    PS选区的应用
    PS界面介绍
    火狐浏览器任务栏设置默认 隐私模式开启
    [CSS] Using inline-grid to gain easy control over gap and size
    [AWS] Presign url for S3
    [CSS] Customer focus / disabled style for select element
    [CSS] Using single grid-template-area and justify-self to select arrow down icon in select
    [CSS 3] Using CSS attribute selector
  • 原文地址:https://www.cnblogs.com/jiangzuofenghua/p/11448547.html
Copyright © 2011-2022 走看看