1.算术运算符重载
我们知道在python中有字符串的相加、数字常量的相加,那么对于我们自定义的类实例化后的对象是否可以进行相加呢?答案是可以的。这里就要我们对于算术运算符进行重载。下面我们以__add__和__iadd__重载为例,讲解算术运算符的重载。
1.1.__add__
__add__是用来定义加法的魔术方法。
我们来看下面的例子,
class Dog:
def __init__(self, amount, name):
self.amount = amount
self.name = name
def __add__(self, other): # 定义两个类相加的结果,other为其他类
return Dog(self.amount + other.amount, self.name) # 返回一个新类
d1 = Dog(23, "Tom")
d2 = Dog(21, "Jerry")
res = d1 + d2 # 等价于 d1.__add__(d2) 等价于 __add__(d1, d2)
print(res)
print(res.amount)
print(res.name)
print(type(res))
执行结果如下,
<__main__.Dog object at 0x000002272FB1A408>
44
Tom
<class '__main__.Dog'>
注意,这里我们定义相加是返回一个新类,而不是一个值。为什么要返回一个类呢?
因为一般来说加法是同类型相加,返回一个同类型的结果。
按照本例来说,一个Dog类和另外一个Dog类结果应该返回一个新的Dog类。两个数字相加应该返回另一个数字,而不应该返回一个字符串。
同时注意,我们仅仅定义了该类的加法原则,并没有改变其他的加法原则。
1.2.__iadd__
__iadd__方法用来定义“+=”的原则。
“+=”与“+”有本质的区别,“+”会产生一个新的结果,并不会改变两个加数的属性值。但是“+=”会改变加数本身的属性值。例如,
class Dog:
def __init__(self, amount, name):
self.amount = amount
self.name = name
def __add__(self, other): # 定义两个类相加的结果,other为其他类
return Dog(self.amount + other.amount, self.name) # 返回一个新类
def __iadd__(self, other): # 定义"+="的结果,other为其他类
self.amount += other.amount # 改变self.amount的属性值
return self # 返回自身
d1 = Dog(23, "Tom")
d2 = Dog(21, "Jerry")
d1 += d2
print(d1.amount)
执行结果如下,
44
2.迭代器
如果想让⼀个类⽤于for-in循环则必须实现__ iter__和__ next__⽅法.。
例如,我们来定义一个输出斐波那契数列的类,
class Fib:
i = 0
def __init__(self, n):
self.n = n
self.x = 0
self.y = 1
def __iter__(self): # 不可或缺
return self # 返回本身
def __next__(self): # 定义下一个返回值
self.__class__.i += 1
self.x, self.y = self.y, self.x + self.y # 迭代
if self.n < self.__class__.i:
raise StopIteration # 停止遍历
return self.x # 返回值
fib1 = Fib(10)
for i in fib1:
print(i)
3.__call__
如果⼀个类实现了__call__(slef, *args, **kwargs)⽅法,则该类的对象可以象函数⼀样调⽤。它是实现类装饰器的基础。
4.单例设计模式
设计模式是指对特定问题的⼀种解决⽅案,和平台、语⾔⽆关。
理解设计模式有助于我们更好的理解⾯向对象,让你的代码更加优雅,使你的代码更加容易扩展和复⽤,同时设计模式也是⾯试时候的重点。
设计模式的基本原则有⾼内聚,低耦合(即尽量使用自己定义的函数和类,不要过多的依赖他人的类和函数);单⼀职责(一个类只为实现一个特定的功能);开闭原则(对修改封闭、对扩展开放。在项目开发的过程中,项目成员会互相使用类和函数,如果我们任意的对已有的类进行修改,会出现他人的代码无法使用的情况)。
所谓单例也就是⼀个类只⽣成⼀个对象,⽆论你实例化多少对象,都是同⼀个对象。常见的单例有数据库操作类,⽂件操作类等。单例可以减少资源的占⽤。
下面我们来定义一个单例,
class Singleton:
__instance = None #保存实例的引⽤
def __new__(cls, *args, **kwargs):
if cls.__instance is None: #如果实例没有实例化
cls.__instance = object.__new__(cls, *args, **kwargs) # 实例化对象,将引⽤存到__instance
return cls.__instance #返回对象
s1 = Singleton()
s2 = Singleton()
print(id(s1), id(s2))
if s1 is s2:
print('单例')
执行结果如下,
2157082821192 2157082821192
单例
来源:CSDN
作者:ForsetiRe
链接:https://blog.csdn.net/ForsetiRe/article/details/104702524