一、算术魔法方法的举例
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()方法,因此他们的实例对象donald和join都可以用作
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 >>>