python-工厂函数
在python2.2之前类与类型分开
类:封装(属性+方法)
类型:整型、浮点型、字符型、字符串型
但之后作者对这俩统一了
将int()、str()、list()这些BIF转化成了工厂函数。
int()与类d的class是一样的,可以把工厂函数看成类,返回实例对象
type(int)
<class 'type'>
class d:
... pass
...
type(d)
<class 'type'>
将类int()进行实例化
a = int('123')
b = int('456')
a+b
579
以前上面的语句是将字符串类型改为整型
现在则是将类int()实例化为a,而“123‘’则是传入的参数
语句:a+b,实际上是对象之间的操作
python专门使用魔法方法定义了对象之间的操作
例如:当检测到对象之间用+号操作时,自动调用int()类中的__add__方法(魔法方法,在需要的时候自动被调用,就像__init__)
下面创建新的类来继承int()的所有方法,然后通过改写__add__方法来让+号不执行相加操作,反而执行相减操作
class re_int(int):
def __add__(self, other): # 检测到对象间“+”号,自动执行该方法
return int.__sub__(self, other) # 返回值为:int()类中的相减操作
def __sub__(self, other): # 检测到对象间“-”号,自动执行该方法
return int.__add__(self, other) # 返回值为:int()类中的相加操作
a = re_int('5')
b = re_int('3')
print(a + b)
2 # 运行结果
如此,我们在类re_int()中交换了符号“+”与符号“-”的作用,使由类产生的实例化对象a与b在执行符号:“+”与“-”的操作时并不像通常认知的那样。
我们仿佛深入到了更加底层的代码,上帝之手像你召唤唤唤唤唤!!!
下面让我们来康康父类int()中的魔法方法是如何实现的:
(dir(类名):查看类中所有方法名和属性名)
(help(类名.方法名):查看类中方法)
help(int.__add__)
Help on wrapper_descriptor:
__add__(self, value, /)
Return self+value.
help(int.__sub__)
Help on wrapper_descriptor:
__sub__(self, value, /)
Return self-value.
上面我们看到了int()类中add方法的实现过程
如果将我们的re_int类不继承int而是自己定义add方法能实现实例对象的加法运算吗?
class re_int(int):
def __add__(self, other,/): # 检测到对象间“+”号,自动执行该方法
return self+other # 返回值为:int()类中的相减操作
def __sub__(self, other,/): # 检测到对象间“-”号,自动执行该方法
return self-other # 返回值为:int()类中的相加操作
a = re_int('5')
b = re_int('3')
print(a+b)
运行结果发现超出做大递归数
Traceback (most recent call last):
File "D:/FishC/作业/41_48_魔法方法/11.py", line 17, in <module>
print(a+b)
File "D:/FishC/作业/41_48_魔法方法/11.py", line 8, in __add__
return self+other # 返回值为:int()类中的相减操作
File "D:/FishC/作业/41_48_魔法方法/11.py", line 8, in __add__
return self+other # 返回值为:int()类中的相减操作
File "D:/FishC/作业/41_48_魔法方法/11.py", line 8, in __add__
return self+other # 返回值为:int()类中的相减操作
[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded
要想正确运行可以在返回前面加上int(),这样返回的是整型的相加
class re_int(int):
def __add__(self, other,/): # 检测到对象间“+”号,自动执行该方法
return int(self)+int(other) # 返回值为:int()类中的相减操作
def __sub__(self, other,/): # 检测到对象间“-”号,自动执行该方法
return int(self)-int(other) # 返回值为:int()类中的相加操作
a = re_int('5')
b = re_int('3')
print(a+b)
例子1:
两个字符串相加会自动拼接字符串,但遗憾的是两个字符串相减却抛出异常。
因此,现在我们要求定义一个 Nstr 类,支持字符串的相减操作:
A – B,从 A 中去除所有 B 的子字符串
class Nstr(str):
def __sub__(self, other):
for each in other:
if each in self:
self = self.replace(each, '')
return str(self)
运行结果:
Nstr类继承str类的所有属性和方法:
检测到减号自动调用__sub__魔法方法
(虽然str类中没有__sub__方法,但是子类Nstr产生的实例遇到“-”号仍然会自动运行__sub__方法)
self是a,other是b
(a与b都是同一个类产生的对象,所以能调用共同的类方法进行操作)
>>> a = Nstr('I love FishC.com!iiiiiiii')
>>> b = Nstr('i')
>>> print(a - b)
I love FshC.com!
例子2:
#定义一个类 Nstr
#当该类的实例对象间发生的加、减、乘、除运算时
#将该对象的所有字符串的 ASCII 码之和进行计算
#查看ASCII: ord(字符)
class Nstr(str):
def __add__(self, other): # 遇到符号:+ 自动运行魔法方法__add__(NB)
s1 = 0
s2 = 0
for each in self:
s1 += int(ord(each))
for each in other:
s2 += int(ord(each))
return s1 + s2
def __sub__(self, other):
s1 = 0
s2 = 0
for each in self:
s1 += int(ord(each))
for each in other:
s2 += int(ord(each))
return s1 - s2
def __mul__(self, other):
s1 = 0
s2 = 0
for each in self:
s1 += int(ord(each))
for each in other:
s2 += int(ord(each))
return s1 * s2
def __truediv__(self, other):
s1 = 0
s2 = 0
for each in self:
s1 += int(ord(each))
for each in other:
s2 += int(ord(each))
return s1 / s2
运行结果:
>>> a = Nstr('FishC')
>>> b = Nstr('love')
print(a+b,a-b,a*b,a/b)
899 23 201918 1.052511415525114
通过以上两个算例我们可以看出:
虽然python没有给我们提供需要的底层功能(比如字符串减法等)
但有了工厂函数我们可以根据需要自己定义需要的功能
这使我们的编程更加的灵活
上一篇: 智能科技、创新未来 2017 iWorld数字世界博览会发布会在蓉举行
下一篇: 大城市压力大