《零基础入门学习Python》(42)魔法方法:算术运算(1)

前提

重新提起一个函数,工厂函数。其实在Python2.2之前类和类型是分开的,类就是一个属性和方法的一个封装,类型就是像(int,float....)。但是2.2之后,作者将两个东西做了统一,将int float等内置函数转化为工厂函数。

举个例子:

>>> type(len)
<class 'builtin_function_or_method'>
>>> type(dir)
<class 'builtin_function_or_method'>
>>> type(int)
<class 'type'>
>>> type(list)
<class 'type'>
>>> class C:
	pass

>>> type(C)
<class 'type'>
>>> int('123')
123
>>> a=int('123')
>>> a
123
>>> b=int('456')
>>> a+b
579

所以工厂函数就是类对象。。。

知识点 :

1.__add__(self,other)魔法方法

>>> class New_int(int):#调用魔法方法__add__,__sub__
	def __add__(self,other):
		return int.__sub__(self,other)
	def __sub__(self,other):
		return int.__add__(self,other)

	
>>> a=New_int(3)
>>> b=New_int(5)
>>> a+b
-2
>>> a-b
8
>>> class Try_int(int):
	def __add__(self,other):
		return self+other#以加法为例,a=self,b=other,然后又返回a+b所以会一直递归
	def __sub__(self,other):
		return self-other
>>> a=Try_int(5)
>>> b=Try_int(6)
>>> a-b
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    a-b
  File "<pyshell#28>", line 5, in __sub__
    return self-other
  File "<pyshell#28>", line 5, in __sub__
    return self-other
  File "<pyshell#28>", line 5, in __sub__
    return self-other
  [Previous line repeated 990 more times]
RecursionError: maximum recursion depth exceeded
>>> a+b
Traceback (most recent call last):
  File "<pyshell#32>", line 1, in <module>
    a+b
  File "<pyshell#28>", line 3, in __add__
    return self+other
  File "<pyshell#28>", line 3, in __add__
    return self+other
  File "<pyshell#28>", line 3, in __add__
    return self+other
  [Previous line repeated 990 more times]
RecursionError: maximum recursion depth exceeded
#更改,改正
>>> 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(3)
>>> b=Try_int(4)
>>> a+b
7

其他的魔法方法在这里可以查找到

测试题

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

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

1.当实例对象进行加法操作时,会自动调用什么魔法方法?

答:对象a和b相加(a+b),Python会自动根据对象a的__add__魔法方法进行加法操作。

2.下面代码有问题吗?(运行起来似乎没出错的说。。。)

>>> class Foo:
	def foo(self):
		self.foo = "T love Fish.com!"
		return self.foo

	
>>> 
>>> foo = Foo()
>>> foo.foo()
'T love Fish.com!'

答:这绝对是一个温柔的陷阱,这种BUG比较难以排除,所以一定要注意:类的属性名和方法名绝对不能相同!如果代码这么写,就会有一个难以排查的BUG出现?

>>> class Foo:
	def __init__(self):
		self.foo = "I love fish..c"
	def foo(self):
		return self.foo

	
>>> foo =Foo()
>>> foo.foo()
Traceback (most recent call last):
  File "<pyshell#49>", line 1, in <module>
    foo.foo()
TypeError: 'str' object is not callable

3.写出下列算术运算符对应的魔法方法?

4.以下代码说明Python支持什么风格?

>>> def calc(a,b,c):
	return (a+b)*c

>>> a=calc(1,2,3)
>>> b=calc([1,2,3],[4,5,6],2)
>>> c=calc('love','FishC',3)
>>> a
9
>>> b
[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
>>> c
'loveFishCloveFishCloveFishC'

答:说明Python支持鸭子类型风格

详见[扩展阅读] 鸭子类型(duck typing)

动动手

0.我们都知道在Python中,两个字符串相加会自动拼接字符串,但遗憾的是两个字符串相减缺抛出异常,因此,现在我们要求定一个Nstr类,支持字符串的相减操作:A-B,从A中去除所有B的子字符串。

>>> class Nstr(str):
	def __sub__(self,other):
		return self.replace(other,'')

	
>>> a=Nstr('I love Ficshc!!!!IIIIIII')
>>> b=Nstr('I')
>>> a-b
' love Ficshc!!!!'

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

>>> class Nstr(str):
	def __lshift__(self,other):
		return self[other:]+self[:other]
	def __rshift__(self,other):
		return self[:-other]+self[-other:]

	
>>> a=Nstr('gogogogogogogobutbecause')
>>> a<<3
'ogogogogogobutbecausegog'
>>> a>>3
'gogogogogogogobutbecause'

2.定义一个类Nstr,当该类的实例对象间发生加,减,乘,除运算时,该对象的所有字符串的ASCLL码之和进行运算?

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

	
>>> 
>>> a=Nstr('Fishc')
>>> b=Nstr('love')
>>> a+b
931
>>> a-b
55
>>> a*b
215934
>>> a/b
1.1255707762557077

猜你喜欢

转载自blog.csdn.net/qq_38721302/article/details/83859691