• 【Python042--魔法方法:算术运算】


    一、算术魔法方法的举例

    1、加法(__add__)的算术运算调用减法(__sub__)的算术运算,减法(__sub__)的算术运算调用加法(__add__)的算术运算

    class New_Init(int):
        def __add__(self,other):
            return int.__sub__(self,other)
        def __sub__(self,other):
            return int.__add__(self,other)
    
        
    >>> a = New_Init('5')
    >>> b = New_Init(6)
    >>> a+b
    -1
    >>> a-b
    11
    >>> 

    2、针对以上需求,现在要求不使用int方法进行运算

    class Try_int(int):
        def __add__(self,other):
            return self+other
        def __sub__(self,other):
            return self+other
    
    >>> a = Try_int(5)
    >>> b = Try_int(6)
    >>> a+b
    Traceback (most recent call last):
      File "<pyshell#19>", line 1, in <module>
        a+b
      File "/Users/wufq/Desktop/加法算术运算.py", line 3, in __add__
        return self+other
      File "/Users/wufq/Desktop/加法算术运算.py", line 3, in __add__
        return self+other
      File "/Users/wufq/Desktop/加法算术运算.py", line 3, in __add__
        return self+other
      [Previous line repeated 990 more times]
    RecursionError: maximum recursion depth exceeded
    
    #不使用int会使程序一直进行递归运算,导致内存不足
    #程序改进
    
    class Try_int(int):
        def __add__(self,other):
            return int(self)+int(other)
        def __sub__(self,other):
            return int(self)+int(other)
    
    >>> a = Try_int(5)
    >>> b = Try_int(6)
    >>> a+b
    11
    >>> 

    二、自Python2.2以后,对类和类型进行了统一, 做法就是将int(),float()、str()、list()、tuple()这些BIF转换为工厂函数,请问所谓的工厂函数,其实是什么原理

    --工厂函数,其实就是一个类对象。当你调用他们的时候,事实上就是创建一个相应的实例对象

    #a,b是工厂函数(类对象)int的实例对象
    
    >>> a = int('123')
    >>> b = int('456')
    >>> a+b
    579
    >>> 

    三、类的属性名和方法名绝对不能相同,否则就会报错

    首先看以下这段代码是否正确:

    class Fool:
        def fool(self):
            self.fool = 'I LOVE AI'
            return self.fool
    
    >>> fool = Fool()
    >>> fool.fool()
    'I LOVE AI'

    看起来没有任何错误,其实写成__init__就会报错

    class Fool:
        def __init__(self):
            self.foo = "I LOVE AI"
        def foo(self):
            return self.fool
    
    >>> fool = Fool()
    >>> fool.fool()
    Traceback (most recent call last):
      File "<pyshell#28>", line 1, in <module>
        fool.fool()
    AttributeError: 'Fool' object has no attribute 'fool'
    >>> 
    
    #属性名fool和方法名fool绝对不能相同

    改进后的代码

    class Fool:
        def __init__(self):
            self.fool = 'I LOVE AI'
        def chk(self):
            return self.fool
    
    >>> f = Fool()
    >>> f.chk()
    'I LOVE AI'
    >>> 
    
    #属性名fool和方法名ckh不一样

    四、写出下列算术运算符对应的魔法方法

    运算符                对应的魔法方法              含义

    +                  __add__(self,other)             加

    -                  __sub__(self,other)             减

    *                  __mul__(self,other)             乘

    /                  __truediv__(self,other)            除

    //                  __foolrdiv__(self,other)            取整除--返回商的整数部分

    %                  __mod__(self,other)             取模--返回除法的余数

    divmod(a,b)              __divmod__(self,other)

    **                   __pow__(self,other[,modulo])            

    <<                  __lshift__(self,other)             左移运算符:运算符的各二进位全部左移若干位,由<<右边的数字指定了移动的位数,高位丢弃,地位补0

                                            实例:a<<2输出结果240,二进制解释:1111 0000

    >>                  __rshift(self,other)

    &                 __and__(self,other)

    ^                  __xor__(self,other)

    |                   __or__(self,other)

     五、鸭子类型

    在程序设计中,鸭子类型(duck typing)是动态类型的一种风格

    在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。

    在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的

    换言之:函数调用了非本类的方法,类的实例对象被用作函数的参数,这就是鸭子类型

    class Duck:
        def quack(self):
            print('呱呱呱')
        def feathers(self):
            print('这个鸭子拥有灰白灰白的羽毛')
    
    class Person:
        def quack(self):
            print('你才是鸭子你全家是鸭子')
        def feathers(self):
            print('这个人穿着一件鸭绒大衣')
    
    def in_the_forest(duck):
        duck.quack()
        duck.feathers()
    
    def game():
        donald = Duck()
        join = Person()
    
        in_the_forest(donald)
        in_the_forest(join)
    
    game()
    
    呱呱呱
    这个鸭子拥有灰白灰白的羽毛
    你才是鸭子你全家是鸭子
    这个人穿着一件鸭绒大衣
    >>> 

    代码含义:

    in_the_forest()函数对参数duck只有一个要求:就是实现了quack()和feathers()方法,然而Duck类和Person()类都实现了quack()和feathers()方法,因此他们的实例对象donaldjoin都可以用作
    in_the_forest()的参数。这就是鸭子类型

     六、

    1、在python中,两个字符串相加会自动拼接字符串,但两个字符串相减会抛出异常。因此,现在我们要求定义一个Nstr类,支持字符串的相减操作:A-B,从A中去除所有B的字符串

    >>> a = '123'
    >>> b = '456'
    >>> a+b
    '123456'
    >>> a-b
    Traceback (most recent call last):
      File "<pyshell#37>", line 1, in <module>
        a-b
    TypeError: unsupported operand type(s) for -: 'str' and 'str'
    >>> 

    采用Nstr类

    class Nstr(str):
        def __sub__(self,other):
            return self.replace(other,'')
        
    >>> a = Nstr('123456789')
    >>> b = Nstr('123')
    >>> a-b
    '456789'

    2、移位操作符是应用于二进制操作数的,现在需要你定义一个新的类Nstr,也支持移位操作符的运算

    需要用__lshift__和__rshift__魔法方法即可

    class Nstr(str):
        def __lshift__(self,other):
            return self[other:]+self[:other]
    
        def __rshift__(self,other):
            return self[-other:]+self[:-other]
    
    >>> a = Nstr('I love AI!!!')
    >>> a<<3
    'ove AI!!!I l'
    >>> a>>3
    '!!!I love AI'
    >>> 

    3、定义一个类Nstr,当该类的实例对象间发生的加,减,乘,除运算时,将该对象的所有字符串的ASCII码之和进行计算

    class Nstr:
        def __init__(self,arg=''):
            if isinstance(arg,str):
                self.total = 0
                for each in arg:
                    self.total +=ord(each)
            else:
                print('参数错误!')
    
        def __add__(self,other):
            return self.total+other.total
    
        def __sub__(self,other):
            return self.total-other.total
        
        def __mul__(self,other):
            return self.total*other.total
    
        def __truediv__(self,other):
            return self.total/other.total
    
        def __floordiv__(self,other):
            return self.total//other.total
    
       
    >>> a = Nstr('FishC')
    >>> b = Nstr('love')
    >>> a+b
    899
    >>> a-b
    23
    >>> a*b
    201918
    >>> a/b
    1.052511415525114
    >>> a//b
    1
    >>> 
  • 相关阅读:
    剑指offer-树的子结构
    剑指offer-二叉搜索树的后序遍历序列
    剑指offer-调整数组顺序使奇数位于偶数前面
    剑指offer-包含min函数的栈
    剑指offer-从上往下打印二叉树
    剑指offer-链表中倒数第k个结点
    剑指offer-合并两个排列的链接
    剑指offer-替换空格
    剑指offer-旋转数组的最小数字
    剑指offer-数字在排序数组中出现的次数
  • 原文地址:https://www.cnblogs.com/frankruby/p/9792465.html
Copyright © 2020-2023  润新知