面向对象
1.单例模式
目的是为了确保某一类只有一个实例存在。我们可以使用__new__来控制实例的创建过程,代码如下:
class Singleton(object): _instace=None #做一个标识 如果等于None说明还没被创建过 def __new__(cls, *args, **kwargs): print('__new__') if cls._instace == None: cls._instace = object.__new__(cls) return cls._instace else: return cls._instace s1=Singleton() s2=Singleton() s3=Singleton() print(id(s1)) print(id(s2)) print(id(s3)) #以上输出得到的ID地址为同一个,证明单例创建成功
在上面的代码中,我们将类的实例和一个类变量_instance关联起来,如果cls._instance为None则创建实例,否则直接返回cls._instance。
2.工厂模式(Simple Factory Pattern)
是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类 并且重写父类方法。
采用简单工厂的优点是可以使用户根据参数获得对应的类实例,避免了直接实例化类,降低了耦合性;
缺点是可实例化的类型在编译期间已经被确定,如果增加新类型,则需要修改工厂,不符合OCP(开闭原则)的原则。
(OCP原则:一个软件应用对扩展开放,对修改关闭)
多态:不同的类对同一个消息/动作做出不同的解释,执行不一样的代码
3个必要条件
1.发生继承关系
2.子类重写父类方法
3.里氏代换原则
好处:节省代码 更符合现实逻辑
下面我们看一个例子:
要求输入两个数和一个运算符,进行四则运算并输出得到结果。
类的结构图:
class Operation: #父类 def __init__(self,num1,num2): self.num1=num1 self.num2=num2 def yunsuan(self): pass class OperationAdd(Operation): def __init__(self,num1,num2): super().__init__(num1,num2) def yunsuan(self): return self.num1 + self.num2 class OperationSub(Operation): def __init__(self,num1,num2): super().__init__(num1,num2) def yunsuan(self): return self.num1 - self.num2 class OperationMul(Operation): def __init__(self,num1,num2): super().__init__(num1,num2) def yunsuan(self): return self.num1 * self.num2 class OperationDiv(Operation): def __init__(self,num1,num2): super().__init__(num1,num2) def yunsuan(self): return self.num1 // self.num2 #工厂类 class OperationFactory(object): @classmethod #classmethod可以通过类方法调用类属性,也可以通过对象调用类属性 def getOperation(self,fu,num1,num2): #getOperation获取运算符 if '+'.__eq__(fu): return OperationAdd(num1,num2) elif '-'.__eq__(fu): return OperationSub(num1,num2) elif '*'.__eq__(fu): return OperationMul(num1,num2) elif '/'.__eq__(fu): return OperationDiv(num1,num2) if '__main__' == __name__: num1=int(input('第一个数')) num2=int(input('第二个数')) fu=input('操作符') #父类类型 容纳子类对象 ->里氏代换原则 operation=OperationFactory.getOperation(fu,num1,num2) js=operation.yunsuan() print('运算结果:',js)
isinstance()函数 判断是否 继承关系 某一个变量是否是某一个数据类型。
上述程序如想输出 判断的哪种继承关系,则可在后面添加以下代码:
if isinstance(operation,OperationAdd): print('创建是的是OperationAdd类型') elif isinstance(operation,OperationSub): print('创建是的是OperationSub类型') elif isinstance(operation,OperationMul): print('创建是的是OperationMul类型') elif isinstance(operation,OperationDiv): print('创建是的是OperationDiv类型')
1).__getattribute__() 访问属性(类名,对象名)
2).__setattr__() 添加属性
3).hasattr(name,str) 判断属性是否存在
在上述工厂中使用这三个函数:
oper=OperationFactory.getOperation('+',6,6) print(oper.__getattribute__('num1')) oper.__setattr__('num3',5) print(oper.__getattribute__('num3')) #得到5 print(hasattr(oper,'num3')) #返回True #若是print(hasattr(oper,'num4')),会返回Flase,因为并没有num4属性
我们还可以给类(只能在类级别添加,所有对象通用,不能给对象添加)动态添加函数,所有对象都能用 。如下:
#继续使用上面的OperationFactory类 #在同级别编写函数 set getName(self,name): self.getName=name #给类添加 一旦类添加了,所有对象都能调用,函数不支持给直接给对象添加 OperationFactory.setName=setName oper=OperationFactory.getOperation('+',6,6) oper.setName='加法' print('运算方式为:',open.setName) #输出得到:运算方式为:加法
4).__slots__变量
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,
来限制该class实例能添加的属性 。例如:
class a(): __slots__ = ('name','age') #限制只能添加'name'和'age'属性 def __init__(self,name,age): self.name=name self.age=age def show(self): print('名字是:',self.name,' 年龄是:'+str(self.age)) if '__main__' == __name__: b=a('汪汪',6) b.c='w' b.show() print(b.c) #因为限制,只允许name 和age ,无法输出c,所有会报错
5).@property
在我们对类属性做一些修改时,需要使用get和set来实现,我们可以使用@property来实现减少代码编写,减少错误的发生。
使用如下:
class Name(): @property def Age(self): #注意,属性名必须一致,如都为Age return self.age @Age.setter def Age(self, age): if age<0 or age>100: print('超出范围,默认18') self.age=18 else: self.age=age print(self.age) name=Name() name.Age=199 #输出 超出范围,默认180
6).__call__()
__call__()可以使一个类实例变成一个可调用对象。如下:
class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def __call__(self, friend): print('My name is %s...' % self.name) print('My friend is %s...' % friend) p = Person('Bob', 'male') p('Tim') #直接调用 #输出 My name is Bob... #输出 My friend is Tim...
7).callable()
callable() 函数用于检查一个对象是否是可调用的。
callable(0) #False def add(a, b): return a + b callable(add) # 函数返回 True #True class A: # 类 def method(self): return 0 callable(A) # 类返回 True #True