【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
>>> 

 

转载于:https://www.cnblogs.com/frankruby/p/9792465.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值