zoukankan      html  css  js  c++  java
  • python进阶之关键字和运算符触发魔法方法

    前言

    python有众多的魔法方法,它们会在满足某种条件下触发执行,掌握好魔法方法的使用,可以加快程序的运行效率,同时减少逻辑调用。

    关键字与魔法方法

    python的一些魔法方法是关键字触发的,即python解释器遇到某个关键字就会去执行相应的魔法方法。

    del与__del__

    如果一个对象定义了__del__魔法方法,那么解释器会调用del关键字后对象的__del__魔法方法,然后在上下文中删除该对象。

    class Dog(object):
        def __init__(self):
            pass
        def __del__(self):
            print('delete the dog object')
    
    dog = Dog()
    del dog # 等价于 dog.__del__()
    

    注意__del__魔法方法做的工作不是删除dog对象,而是在删除dog对象发生之前调用,是删除之前的钩子。

    with与__enter__、__exit__

    如果一个类实现了_enter_、__exit__魔法方法,我们就说这个类实现了一个上下文管理器,它使用with关键字触发,更多的用法参考:python之上下文管理器

    if与__bool__

    一个对象定义了__bool__魔法方法后,if关键字会触发该魔法方法,如果没有定义就会使用解释器预置的处理算法。

    class List(list):
        def __bool__(self):
            print('list bool')
            return True
    if __name__ == "__main__":
    ls = List([])
    if ls: # 为真,等价于bool(ls)
        print('mmm')
    

    in ot in与__contains__

    当使用in或not in关键字判断一个容器里的元素时,触发该容器的_contains_,如果没有定义,Python就会迭代整个序列.

    class MyList(list):
        def __contains__(self, item):
            print('__contains__')
            return super().__contains__(item) # 返回True或False
    
    if __name__ == "__main__":
        my = MyList([1,2,3])
        if 1 in my: # 等价于 bool(my.__contains__(1))
            pass
    

    运算符与魔法方法

    python像大多数编程语言一样有那么多的运算符,为什么哪些运算符有着相应的功能呢?答案就在于运算符会触发相应的魔法方法。

    python的运算符有算术运算符、逻辑运算符、比较运算符等:

    算术运算符与魔法方法

    • +:数值相加,会调用相加对象的__add__或__radd__方法。
    class Int(int):
        def __add__(self, other):
            print('diao yong le add')
            return super().__add__(other)
    
        def __radd__(self, other):
            print('diao yong le radd')
            return super().__radd__(other)
    if __name__ == "__main__":
        a = Int(3)
        b = Int(5)
        c = a + b # 方法__add__方法被调用了
        c = 3 + a # 方法__radd__方法被调用了,即py会优先调用自定义的对象的__add__和__radd__方法,如果没有才调用内置对象的相关方法。
    

    我们可以通过重写相关的方法重新定义“+”符号的功能。

    同理算术运算符的魔法方法:

    a+b:数值相加,会调用对象的\__add\__或\__radd__方法。
    a-b:数值相减,会调用对象的__rsub__或__sub__方法
    a*b:数值相乘,调用__mul__和__rmul__方法
    a/b:数值相除,调用__rtruediv__和__truediv__方法
    a//b:整除,调用__floordiv__和__rfloordiv__方法。
    a%b:求余,调用__mod__和__rmod__方法
    a**b:求幂,调用__pow__和__rpow__方法;
    -a:求负数,调用__neg__方法;
    +a:调用__pos__方法
    

    赋值运算符与魔法方法

    a+=b:a与b相加赋值给a,调用__iadd__方法;
    a-=b:a与b相减赋值给a,调用__isub__方法;
    a*=b:a与b相乘赋值给a,调用__imul__方法;
    a/=b:a与b相除赋值给a,调用__itruediv__方法;
    a%=b:a与求余赋值给a,调用__imod__方法;
    a//=b:a与b整除赋值给a,调用__ifloordiv__方法;
    a**=b:a与b求幂赋值给a,调用__ipow__方法;
    a&=b:a与b位与运算赋值给a,调用__iand__方法;
    a|=b:a与b位或运算赋值给a,调用__ior__方法;
    a^=b:a与b位异或运算赋值给a,调用__ixor__方法;
    

    比较运算符与魔法方法

    >:大于,比较大小返回布尔值,调用比较参数的\__gt__方法
    >=:大于等于,调用比较参数的\__ge__方法
    <:小于,调用比较参数的\__lt__方法
    <=:小于等于,调用比较参数的\__le__方法
    ==:等于,调用比较参数的__eq__方法
    !=:不等于,调用比较参数的__ne__方法
    

    位运算符与魔法方法

    位运算符是将数字当做位来运算.

    a = 10 # 位 a = 0000 1010
    b = 15 # b = 0000 1111
    c = a&b # c = 0000 1010
    print(c) # 10
    

    相应的魔法方法:

    |:或,调用比较参数的__or__和__ror__方法
    &:与,调用比较参数的__and__和__rand__方法
    ~:取反,调用比较参数的__invert__方法
    <<:左移位运算,调用比较参数的__lshift__和__rlshift__方法
    >>:右移动运算符,调用比较参数的__rrshift__和__rshift__方法
    ^:异或运算,调用比较参数的__rxor__和__xor__方法
    

    参考

  • 相关阅读:
    PHP 创建二叉树镜像(交换左右子树)
    PHP 使用二叉树的先序和中序遍历结果构造二叉树
    PHP 不用求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)
    PHP 不用加减乘除做加法
    PHP 跳台阶问题
    PHP 输入一个整数,求该整数的二进制表达中有多少个1
    PHP 输入两个整数n 和m,从数列1,2,3.......n 中随意取几个数, 使其和等于m ,要求将其中所有的可能组合列出来
    PHP 查找链表倒数第i个节点
    .Net/C# 实现: FlashFXP 地址簿中站点密码的加解密算法
    johnsuna 的收藏精品
  • 原文地址:https://www.cnblogs.com/cwp-bg/p/9856065.html
Copyright © 2011-2022 走看看